3

I want to build a column layout with a menu, then a header, then a content container using flexboxes.

I know how to build it in other techs using fixed sizes, calc etc... But have troubles with flexboxes.

Here is a JsFiddle

I have this:

<div class="layout">
  <div class="menu">
    Menu
  </div>
  <div class="header">
    Header
  </div>
  <div class="content">
    <div class="scrollable-content">
      ...
    </div>
  </div>
</div>

.layout {
  overflow: hidden;
  border: solid;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.menu {
  overflow: hidden;
  border: solid red;
  flex-grow: 0;
  flex-shrink: 0;
}

.header {
  overflow: hidden;
  border: solid green;
  flex-grow: 0;
  flex-shrink: 0;
}

.content {
  overflow: hidden;
  border: solid blue;
  flex-grow: 1;
  flex-shrink: 1;
}

.scrollable-content {
  overflow: auto;
  height: 100%;
  width: 100%;
}

As you can see on the JsFiddle, with this code, the .scrollable-content is actually never scrollable, because even while using height: 100% it becomes much larger than his parent div. How can I constrain that div's height to the parent's height?

Note: I know I could put the overflow: auto to the parent .content directly, but for reasons specific to my app I really don't want to: please only submit solutions that do not modify the html structure or change the scrollable container because I already know these solutions. I'm more interested to learn why my approach did not work and how it could be fixed (or not?)

Obviously the content that can be scrolled has a dynamic height and is not a fixed value of 450px like in my JsFiddle.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419

3 Answers3

3

You could remove height: 100% from .scrollable-content, and then change the display of .content to flex:

Updated Example

.content {
  overflow: hidden;
  border: solid blue;
  flex-grow: 1;
  flex-shrink: 1;
  display: flex;
}

.scrollable-content {
  overflow: auto;
  width: 100%;
}
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
1

You're missing a height: 100% on .content.

Since you're using percentage heights, you need to specify a height for all parent elements of the .scrollable-content.

For a more detailed explanation see: Working with the CSS height property and percentage values

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    No because I don't want the `.content` to be 100% of its parent: I want it to grow and fill the empty space. See the problem: the `.content` would overflow the `.layout` then – Sebastien Lorber Dec 28 '15 at 17:24
  • 1
    I understand, but you would *need* to specify a height on `.content` for percentage heights to work on `.scrollable-content`. This is per the spec. Currently it's resolving to `height: auto`. Alternatively, you could forgo percentage heights for another method, such a nested flexbox, perhaps. – Michael Benjamin Dec 28 '15 at 17:26
  • The point of using `flex-grow` in the first place was to be able to take all the empty space without having to take care of giving the size :) I already know I can compute the heights myself but was looking to avoid this because actually some parts of my layout can be added or removed dynamically according to context – Sebastien Lorber Dec 28 '15 at 17:26
0

You are almost there.

   .content {
       overflow: hidden;
       border: solid blue;
       flex-grow: 1;
       flex-shrink: 1;
       height:450px;  //adjust accordingly.
   } 

The scroll activates once a height a limited height has been reached. In your case since you have the scrollable area limited to the parent's (content) height, you did right by giving it height: 100%....but....100% of what?

So, all you need is give the content class a stopping point. change the 450px to whatever is more suitable. If you are trying to cover for a gap below that content then the next item should be positioned absolute bottom. (just in case that is what you are tying to get to) I've seen this approach many times and that is usually what follows :)

Here is your updated jfiddle

LOTUSMS
  • 10,317
  • 15
  • 71
  • 140
  • the point of using flex-grow is to not have to specify any height. I already know how to achieve this layout by using static heights or `calc()`. – Sebastien Lorber Dec 28 '15 at 17:30