Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a div scroll instead of expanding to fit its contents

Tags:

html

css

I have a layout where I have a scrollable list of items in the center, with some stuff above and below it in a column. The list should take up as much empty space as is available to it in the column (I don't want to specify a specific height on it), and should scroll when the empty space in the column is not enough to fit all the items.

Here is a JSFiddle of the situation.

Notice that with just a few items in the scroller, it expands to fill the empty space in the column (as is intended). But then if you add several more items to the scroller, it expands to fit the entirety of its contents instead of staying at its original size, and then scrolling its overflowing contents; even though the it has overflow-y: scroll set!


However, if you then set the scroller to have a height of 0, the problem is fixed and the items scroll as is intended, with the scroller at its original height before the extra items were added.

But WHY!? Can someone please explain to me what's going on here? Also, is there any consequences of this "solution" that I'm not seeing?


<div class="column">
  <div class="title">Header</div>
  <div class="scroller">
    <div class="item">Child</div>
    <div class="item">Child</div>
  </div>
  <div class="title">Footer</div>
</div>

,

.column {
  display: flex;
  flex-direction: column;
  height: 200px;
}

.title {
  height: 50px;
  flex-shrink: 0;
}

.scroller {
  flex-grow: 20;
  flex-shrink: 0;
  overflow-y: scroll;
}

.item {
  height: 20px;
  margin-top: 2px;
}
like image 455
Zach Posten Avatar asked Aug 30 '25 18:08

Zach Posten


1 Answers

Some quick background for anyone who runs across this later:

Elements that have flex-grow expand to take up x units of the available space minus the other flex content. In your case, .scroller is the only one with flex-grow but the other flex elements have defined heights so their content takes up space.

Elements that have flex-shrink contract as the space decreases. A zero value means they don't contract, a value >=1 allows scaling down.

However flex-shrink ONLY works if the element DOES NOT also have a flex-grow applied to it. Elements with both shrink & grow will only shrink to the size of their content

In your example, overflow doesn't kick in when the element is as big as the content (see above) which it is because you have both grow/shrink applied. Adding an explicit height (height: 0) overrides the computed "content" height allowing the flex-shrink to compress the element smaller than its content. This, in turn, makes the scrollbar work.

I don't know if this will cause any oddities at some point but it's an interesting solution to the problem and does seem to work pretty well.

like image 148
Bryce Howitson Avatar answered Sep 02 '25 07:09

Bryce Howitson