Flexbox container shrinking below min-height: max-content

226 views Asked by At

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 container minimizable-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:

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>

1

There are 1 answers

0
M-WRI On

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:

* {
  min-height: 0px;
}

html,
body {
  position: absolute;
  margin: 0px;
  padding: 0px;
  overflow: hidden;
  top: 0px;
  left: 0px;
  height: 100%;
  width: 300px;
}

body {
  display: flex;
  flex-direction: column;
}

.container {
  display: grid;
  align-content: start;
  height: 100%;
  width: 300px;
  overflow: auto;
}

.minimizable-group {
  display: grid;
  grid-template-rows: auto 1fr;
}

.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 {
  overflow-y: auto;
}

.minimizable-group-content.minimized {
  display: none;
}

.unshrinkable {
  background-color: #ffcccb;
  min-height: max-content !important;
}

.shrinkable {
  background-color: #add8e6;
  min-height: 1em;
  overflow-y: auto;
}