I am working on a flexbox side bar menu, but seem to be running into conflicts between flex: 0 1 auto
containers with an intrinsic size for min-height
, causing the containers to shrink below the allowed minimum.
JSFiddle Link (same as snippet below)
Summary / Intended behavior
- The menu spans the entire vertical screen space and consists of an arbitrary number of
minimizable-group
containers that are neatly stacked on top of each other. - Each group has a
flex: none
header/title and a flexible containerminimizable-group-content
- There are two group-content types:
.unshrinkable
for important control elements that should remain fully visible to the user (red boxes in snippet).shrinkable
for potentially huge lists, which are allowed to shrink to some minimum height (blue boxes in snippet)
- Each minimizable group can be collapsed by the user (⮟ button) -- that part works fine currently.
Issue
In the snippet you can see all three minimizable groups (in full-screen). The unshrinkable content in Group 2 however gets squeezed together, unless I collapse either Group 1 or Group 3
From looking at the Dev Console, it seems the problem is in minimizable-group-content
. The red .unshrinkable
box inside shows a reasonable calculated height (18 pixel), but the enveloping container only has a calculated height of ~5px and refuses to resize no matter what CSS I throw at it.
Is there any other property I can set to prevent my flex boxes to shrink past the minimum height? Or can I get the intended behavior with a different approach?
(Not) related:
- Parent flexbox container ignores child's flexbox min-width -- used that as well, but covers the exact opposite: elements not shrinking
- https://github.com/philipwalton/flexbugs#flexbug-1 -- would match, but it seems that one is fixed already
- How do min-content and max-content work? -- explanation for intrinsic dimensions - which I think I am using correctly?
- Safari: flexbox and min-height -- tried fit-content/min-content/max-content, but none seem to have any effect
Snippet
Array.from(document.getElementsByClassName("minimizable-group")).forEach((element) => {
element.children[0].addEventListener('click', () => {
element.children[0].classList.toggle('minimized');
element.children[1].classList.toggle('minimized');
});
});
* {
min-height: 0px;
}
html,
body {
position: absolute;
margin: 0px;
padding: 0px;
overflow: hidden;
top: 0px;
left: 0px;
height: 100vh;
width: 300px;
}
body {
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: column;
flex: 0 1 auto;
overflow-y: auto;
}
.minimizable-group {
display: flex;
flex-direction: column;
flex: 0 1 auto;
overflow-y: hidden;
}
.minimizable-group-title {
flex: none;
}
.minimizable-group-content {
display: flex;
flex-direction: column;
flex: 0 1 auto;
overflow-y: auto;
min-height: min-content !important;
}
.unshrinkable {
flex: none;
min-height: max-content !important;
}
.shrinkable {
flex: 0 1 auto;
overflow-y: auto;
min-height: 1em;
}
/*********************************/
/* IRRELEVANT STUFF BELOW */
.minimizable-group-title {
cursor: pointer;
color: #aaa;
background-color: #333;
font-weight: bold;
}
.minimizable-group-title::before {
content: '⮟ ';
}
.minimizable-group-title.minimized::before {
content: '➤ ';
}
.minimizable-group-content.minimized {
max-height: 0px;
visibility: hidden;
}
.unshrinkable {
background-color: #ffcccb;
}
.shrinkable {
background-color: #add8e6;
}
<div class="container">
<div class="minimizable-group">
<div class="minimizable-group-title">Group 1</div>
<div class="minimizable-group-content">
<div class="unshrinkable">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
<div class="shrinkable">Amet venenatis urna cursus eget nunc. Sapien nec sagittis aliquam malesuada. Tortor vitae purus faucibus ornare suspendisse. Cursus eget nunc scelerisque viverra mauris in aliquam sem. Et leo duis ut diam quam. Nisl suscipit adipiscing bibendum
est ultricies integer quis auctor. Volutpat maecenas volutpat blandit aliquam etiam erat. Fames ac turpis egestas integer eget aliquet nibh. Enim praesent elementum facilisis leo vel. Enim facilisis gravida neque convallis a. Et magnis dis parturient
montes nascetur ridiculus mus mauris vitae. Amet est placerat in egestas.
<p /> Vel eros donec ac odio tempor. Purus gravida quis blandit turpis cursus in hac habitasse platea. In aliquam sem fringilla ut morbi tincidunt augue interdum. Diam ut venenatis tellus in metus. Vitae purus faucibus ornare suspendisse sed nisi lacus
sed. Velit sed ullamcorper morbi tincidunt. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Augue mauris augue neque gravida in fermentum. Nunc aliquet bibendum enim facilisis gravida neque convallis a cras. Sem et tortor consequat
id. Diam sollicitudin tempor id eu nisl nunc mi ipsum. Eros donec ac odio tempor orci dapibus ultrices.
</div>
<div class="unshrinkable">
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
<div class="minimizable-group">
<div class="minimizable-group-title">Group 2</div>
<div class="minimizable-group-content">
<div class="unshrinkable">Elementum sagittis vitae et leo duis</div>
</div>
</div>
<div class="minimizable-group">
<div class="minimizable-group-title">Group 3</div>
<div class="minimizable-group-content">
<div class="unshrinkable">Facilisis volutpat est velit egestas dui id ornare arcu odio. Duis ultricies lacus sed turpis tincidunt id.</div>
<div class="shrinkable">Amet venenatis urna cursus eget nunc. Sapien nec sagittis aliquam malesuada. Tortor vitae purus faucibus ornare suspendisse. Cursus eget nunc scelerisque viverra mauris in aliquam sem. Et leo duis ut diam quam. Nisl suscipit adipiscing bibendum
est ultricies integer quis auctor. Volutpat maecenas volutpat blandit aliquam etiam erat. Fames ac turpis egestas integer eget aliquet nibh. Enim praesent elementum facilisis leo vel. Enim facilisis gravida neque convallis a. Et magnis dis parturient
montes nascetur ridiculus mus mauris vitae. Amet est placerat in egestas.
<p /> Vel eros donec ac odio tempor. Purus gravida quis blandit turpis cursus in hac habitasse platea. In aliquam sem fringilla ut morbi tincidunt augue interdum. Diam ut venenatis tellus in metus. Vitae purus faucibus ornare suspendisse sed nisi lacus
sed. Velit sed ullamcorper morbi tincidunt. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Augue mauris augue neque gravida in fermentum. Nunc aliquet bibendum enim facilisis gravida neque convallis a cras. Sem et tortor consequat
id. Diam sollicitudin tempor id eu nisl nunc mi ipsum. Eros donec ac odio tempor orci dapibus ultrices.</div>
</div>
</div>
</div>
It seems that your question was posted 3 years ago, but I believe I have a solution for you now. I understand from your question that you'd like the unshrinkable class items to always maintain their intended height.
To address this, I suggest using CSS Grid instead of Flexbox for structuring your layout. CSS Grid offers a more robust solution for complex designs, especially when it comes to aligning and spacing of your items.
Here's the proposed modification to your CSS: