firefox overflow-y not working with nested flexbox
tl;dr: you need min-height:0
in your .level-0-row2
rule. (Here's a codepen with that fix.)
More detailed explanation:
Flex items establish a default minimum size that's based on their children's intrinsic size (which doesn't consider "overflow" properties on their children/descendants).
Whenever you've got an element with overflow: [hidden|scroll|auto]
inside of a flex item, you need to give its ancestor flex item min-width:0
(in a horizontal flex container) or min-height:0
(in a vertical flex container), to disable this min-sizing behavior, or else the flex item will refuse to shrink smaller than the child's min-content size.
See https://bugzilla.mozilla.org/show_bug.cgi?id=1043520 for more examples of sites that have been bitten by this. (Note that this is just a metabug to track sites that were broken by this sort of issue, after this spec-text was implemented -- it's not actually a bug in Firefox.)
You won't see this in Chrome (at least, not as of this posting) because they haven't implemented this minimum sizing behavior yet. (EDIT: Chrome has now implemented this min-sizing behavior, but they may still incorrectly collapse min-sizes to 0 in some cases.)
rekna
Updated on July 22, 2021Comments
-
rekna almost 3 years
I have designed a 100% width 100% height layout with css3 flexbox, which works both on IE11 (and probably on IE10 if emulation of IE11 is correct).
But Firefox (35.0.1), overflow-y is not working. As you can see in this codepen : http://codepen.io/anon/pen/NPYVga
firefox is not rendering overflow correctly. It shows one scrollbar
html, body { height: 100%; margin: 0; padding: 0; border: 0; } .level-0-container { height: 100%; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } .level-0-row1 { border: 1px solid black; box-sizing: border-box; } .level-0-row2 { -webkit-box-flex: 1; -webkit-flex: 1; -ms-flex: 1; flex: 1; border: 1px solid black; box-sizing: border-box; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; -ms-flex-direction: row; flex-direction: row; } .level-1-col1 { width: 20em; overflow-y: auto; } .level-1-col2 { -webkit-box-flex: 1; -webkit-flex: 1; -ms-flex: 1; flex: 1; border: 4px solid blue; box-sizing: border-box; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } .level-2-row2 { -webkit-box-flex: 1; -webkit-flex: 1; -ms-flex: 1; flex: 1; border: 4px solid red; box-sizing: border-box; overflow-y: auto; }
<html> <body> <div class="level-0-container"> <div class="level-0-row1"> Header text </div> <div class="level-0-row2"> <div class="level-1-col1"> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> line <br/> </div> <div class="level-1-col2"> <div class="level-2-row1"> Some text <p/> Some text 2 <p/> Some text 3 <p/> </div> <div class="level-2-row2"> <p>some text</p> <p>some text</p> <p>some text</p> <p>some text</p> <p>some text</p> <p>some test</p> </div> </div> </div> </div> </body> </html>
-
Ambroz Bizjak about 8 yearsI've hit this issue but I had to add min-height:0 to all the parent flexbox columns - any idea why?
-
Sam Storie about 8 yearsDoes this min-height (in my case) need to be applied to every ancestor? Or just the immediate parent?
-
dholbert almost 8 yearsIt potentially needs to be applied to every ancestor that is a flex item (i.e. every ancestor whose parent is
display:flex
), depending on the circumstances. -
trysis over 7 yearsAre there any plans to change the spec to take overflow into account? Now that I know why this happens I can work around it, but it will still be annoying.
-
dholbert over 7 yearsRE spec changes -- I asked about this on the CSS working group list, and the spec editor replied that "we don't think it's possible to address this in any sane way" (and I agree, given the primitives that CSS has to work with). lists.w3.org/Archives/Public/www-style/2014Aug/0282.html So you'll likely continue to need
min-width:0
/min-height:0
hackarounds for situations like this, going forward. -
Brett over 7 yearsAny reason we can't just apply
* { min-height: 0; min-width: 0; }
? -
dholbert over 7 yearsYou could do that, but that would disable the Good Things that the magic
min-width:auto
behavior brings. In particular: flex items are set up to be shrinkable down to their resolvedmin-width
(ormin-height
if vertical) by default, by virtue of havingflex-shrink:1
in their initial style. So if you setmin-width
(ormin-height
) to 0, then your flex items will let themselves shrink down to 0 by default, which might not be what you want -- particularly if it's just because another greedy flex item is stealing all of the space. -
dholbert over 7 years@Brett, here's a jsfiddle demonstrating the sort of badness (content overflowing/overlapping) that can arise from using
min-width:0
too aggressively: jsfiddle.net/85scnr1b So really, you only want to addmin-width:0
on flex items whose content can "behave nicely" if it's given an arbitrarily-smallerwidth
than it expects. (Same goes formin-height
&height
, for vertical flex containers.) -
Ashok Koyi about 7 yearsIn my case even setting min-height on all ancestors is not working. I have to compute the height at runtime using window.getComputedStyle & calculate the height that can be taken by the scrollable area. I'm using chrome. Any reason why this might be the case?
-
Boog over 6 yearsFor whatever reason adding min-height:0px to my parent flex item resolved this issue for me, setting it on child-ancestors appeared to have no affect. Issue was only occurring in FF.