3

I'm currently experimenting with flexbox layouts and have a problem, that overflow wont get applied, when I nest multiple flexboxes.

As long as I just use one level of flex boxes (see example 1), everything works fine: As soon as its content exceed the given space, scrollbars are applied to the red box (#top).

If I, however, introduce another layer of flexboxes (see example two), there is no scrollbar on the blue box (#right). Instead the scrollbars appear on the body element completely ignoring the overflow: auto setting on the blue box.

So my question is: How can I get overflow to work when using nested flexboxes?

Remark: I tested this with Chrome45, Firefox 40 and IE11. The behavior is consistent across all.

Below is the code as well as a fiddle link for both cases.


(1) Just one flexbox, no nesting

Fiddle

<div id="container">
    <div id="top">
      ...
    </div>
    <div id="bottom">
        blub
    </div>
</div>

 

html, body { 
    width: 100%; 
    height: 100%; 
    margin: 0; 
    padding: 0;
}

#container{
    background-color: yellow;
    flex-direction: column;
    display: flex;
    height: 100%;
}

#top {
    background-color: red;
    flex-grow: 1;
    display: flex;
    flex-direction: row;
        overflow: auto;
    white-space:pre;
}


#bottom {
    background-color: green;
    height: 4em;
}


(2) nested flexboxes

Fiddle

<div id="container">
    <div id="top">
        <div id="left">
        </div>
        <div id="right">
          ...
        </div>
    </div>
    <div id="bottom">
        blub
    </div>
</div>

 

html, body { 
    width: 100%; 
    height: 100%; 
    margin: 0; 
    padding: 0;
}

#container{
    background-color: yellow;
    flex-direction: column;
    display: flex;
    height: 100%;
}

#top {
    background-color: red;
    flex-grow: 1;
    display: flex;
    flex-direction: row;
}

#right {
    white-space: pre;
    overflow: auto;
    background-color: blue;
    width: 5em;
}

#left {
    flex-grow: 1;
    background-color: orange;
}

#bottom {
    background-color: green;
    height: 4em;
}
Sirko
  • 72,589
  • 19
  • 149
  • 183

2 Answers2

5

Latest browsers implement the new auto as the initial value of min-height.

That forces #top to be at least as tall as its content.

So you need to undo that:

#top {
  min-height: 0;
}

Then #top can be shorter than its content. #right will be stretched to be as tall as #top, and the content of #top might overflow.

html, body { 
  width: 100%; 
  height: 100%; 
  margin: 0; 
  padding: 0;
}
#container{
  background-color: yellow;
  flex-direction: column;
  display: flex;
  height: 100%;
}
#top {
  background-color: red;
  flex-grow: 1;
  display: flex;
  flex-direction: row;
  min-height: 0;
}
#right {
  white-space: pre;
  overflow: auto;
  background-color: blue;
  width: 5em;
}
#left {
  flex-grow: 1;
  background-color: orange;
}
#bottom {
  background-color: green;
  height: 4em;
}
<div id="container">
  <div id="top">
    <div id="left">
    </div>
    <div id="right">
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
      11
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
      1
    </div>
  </div>
  <div id="bottom">
    blub
  </div>
</div>
Oriol
  • 274,082
  • 63
  • 437
  • 513
0

Alternative answer: just specify flex:1 rather than flex-grow:0 on #top. Or specify flex-basis:0. flex:1 implicitly sets flex: 1 1 0, i.e. the third 0 means flex-basis:0.

This matters because the default initial value of flex-basis is not 0 but auto, which in turn effectively means content-sized and thus you need to resort to min-height. Like the OP, I found min-height somewhat out-of-nowhere and a bit bewildering, and the flex notation less so.

Updated snippet:

http://codepen.io/yaaang/pen/gayqPE

From the spec:

[The third component in flex] sets the flex-basis longhand and specifies the flex basis: the initial main size of the flex item, before free space is distributed according to the flex factors. It takes the same values as the width property (except auto is treated differently) and an additional content keyword. When omitted from the flex shorthand, its specified value is 0%.

If the specified flex-basis is auto, the used flex basis is the computed value of the flex item’s main size property. If that value is itself auto, then the used flex basis is automatically-determined based on its content (i.e. sized as for content).

Yang
  • 16,037
  • 15
  • 100
  • 142