2

In the following questions, I've been able to get all the cases to work out, I'm just looking to debug my mental model. I'm also only concerned with Chrome, if that makes answering easier.

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.

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?

Also, the element I need to slap the min-height:0 onto is .orange. Why this element, and why not the other ancestors?

Can anyone explain the above two questions? I have been consulting the spec and am having trouble connecting its rules back to my 4-level-deep example.

Note that this is different from the other questions I've been able to find on SO regarding flexbox and overflow, for instance (see in particular my answers):

overflow: auto in nested flexboxes

Nested flexbox with scrolling area

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Yang
  • 16,037
  • 15
  • 100
  • 142

1 Answers1

1

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

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701