I have an overflow:auto
within nested "holy grail-ish" flexbox layouts. The overflow:auto
behavior works fine for 2-level and 3-level nesting.
Your 2-level code does indeed work as intended in Chrome, and IE11. However, it fails in Firefox. Same thing with your 3-level code: Works in Chrome and IE11, but not Firefox.
However, once I get to 4-level nesting, it "breaks," requiring me to specify the min-height:0
property (despite my having consistently specified flex-basis:0
via flex:1
, which should annul the flex-basis:content
/content-sized
default). Why is this only happening at 4-level nesting?
Once again, your statement is true for Chrome and IE11, but not for Firefox.
Solutions
Let's start with the fixes, so that all demos work in Chrome, Firefox and IE11. (I didn't test in Safari, but that's WebKit like Chrome, so it should be fine with vendor prefixes for any versions prior to 9.)
Also, I'll use compiled code in the answer, as not everybody uses preprocessors.
Revised 2-level (added two lines of code)
.violet {
flex: 1;
background: violet;
display: flex;
flex-direction: column;
min-height: 0; /* new */
min-width: 0; /* new */
}
Revised 3-level (added four lines of code)
.violet {
flex: 1;
background: violet;
display: flex;
flex-direction: column;
min-height: 0; /* new */
min-width: 0; /* new */
}
.orange {
flex: 1;
background: orange;
display: flex;
min-height: 0; /* new */
min-width: 0; /* new */
}
Revised 4-level (added one line of code)
.violet {
flex: 1;
background: violet;
display: flex;
flex-direction: column;
/* For some reason this is not needed */
/* min-height:0; */
min-width: 0; /* new */
}
Breaking Down the Behavior
There's a lot going on with your nesting. I'm not going to debug the code line-by-line, but I'll offer three concepts that may be useful to you.
1. Calculating Percentage Heights
Chrome, Firefox and IE11 can have different interpretations for an element's height.
Here's what it says in the spec:
CSS height
property
percentage
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes to "auto".
auto
The height depends on the values of other properties.
Traditionally, when calculating percentage heights, browsers have interpreted the spec's use of the term "height" to mean the value of the height
property.
Based on a reading of the height
definition, the interpretation could just as easily be the computed height, but the height
property requirement has become the predominant implementation. I've never seen min-height
or max-height
work on a parent when dealing with percentage heights.
Chrome expects to see the height
property when calculating height. If it doesn't, it computes the height to auto
. Firefox, however, has a broader interpretation of the spec. It accepts flex heights, as well (as evidenced here and here and here).
It's not clear which browsers are more compliant.
It doesn't help matters that the height
property definition hasn't been updated since 1998 (CSS2).
In all three of your demos you're combining percentage heights, pixel heights and flex heights. You may want to keep the differing browser interpretations in mind when troubleshooting your code.
Here are some more details: Working with the CSS height
property and percentage values
2. Why doesn't flex item shrink past content size?
3. flex-basis: 0
vs flex-basis: auto
flex: 1 1 auto
(or flex: auto
, for short), sizes a flex item based on the content size or height properties.
flex: 1 1 0
(or flex: 1
, for short), sizes a flex item based on the free space in the flex container.
Each may have a different effect on the behavior of overflow: auto
.
More details here: Page-filling flexbox layout with top and side bars not quite working