Flexbox in Chrome--How to limit size of nested elements? [duplicate]
This question already has an answer here:
In Google Chrome, how do I force an element nested inside of a member of a flexbox (by "member of a flexbox" I mean a child of an element styled with
display:flex) to limit its size to the size of the flexbox member it's nested under? For example, suppose I have the following:
<div style="display:flex; flex-direction:column; height:100vh;"> <div style="height:60px;">Static header</div> <div style="flex: 1 1 0; overflow:hidden;"> <div style="overflow:auto; height:100%;" id="problem-is-here"> Lots and lots of content, way too much to fit in the viewport </div> </div> </div>
Because the first child
div of the outermost
div has a constant height, it ends up exactly 60px tall, and because the second child
div has a
flex-grow of 1, it gets the rest of the space available (in this case, 100% of the viewport minus 60px). I can confirm that this element's dimensions according to Inspect Element are just large enough to take up the rest of the viewport space.
In Firefox and IE11, due to the
height:100%, the innermost element (
id="problem-is-here") takes on the height computed for its parent. Therefore, since it is too small to display its content and
overflow is set to
auto, it (and not the entire
body) gets a vertical scrollbar. This is what I want.
In Chrome, however, the innermost element is rendered with enough height to contain all of its content, which is a larger height than its parent. Thus, because its parent has
overflow:hidden, no scrollbar appears and the excess content is inaccessible. How do I tell Chrome to render this innermost element with height at most equal to that of its parent, when the parent height is determined by a flexbox, not a CSS
height property? Note that I can't give either the innermost
div or its parent a definite
height value since in the application I'm working on, the number of other flexbox members can vary.
Note: I have tried a few suggestions from other answers, such as setting all elements to have
min-height:0 instead of
auto, or ensuring
flex-basis is set to
0, but none of these have worked. See
for an example that illustrates the problem. (The
div with id
heres-the-problem is the one whose height I want limited to the height of its parent.)
First, let's tackle the terminology:
...how do I force an element nested inside of a member of a flexbox (by "member of a flexbox" I mean a child of an element styled with
display:flex) to limit its size to the size of the flexbox member it's nested under?
An element with
display: flex is called a flex container (technically) or flex parent (colloquially).
The children of a flex container are called flex items. Note the word children (first-level). Descendents of a flex container beyond the children are not flex items and most flex properties don't apply to them.
Now, addressing your question:
The problem is that Firefox (and apparently IE11) have a different interpretation of the percentage height rule than Chrome.
Specifically, the vertical scrollbar you want is not rendering in Chrome because you're using percentage heights in a way that doesn't conform with the traditional implementation of the spec.
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".
The height depends on the values of other properties.
In other words, if you want an element to have a percentage height, then you must specify a height on the containing block (i.e. the parent).
In your code,
body (level 1) has
One level down,
.max-flex (level 2) has
Four levels down,
.large-nested-div (level 4) has
.variable-flex-content (level 3), there is no
height property. You are defining the height with
flex: 1 1 0. As far as Chrome is concerned, this is a missing link in the chain and a violation of the spec. Chrome is expecting to see the
height property, and when it doesn't, it computes the height to
Chrome vs Firefox (I haven't tested IE11, so I won't mention it here)
Traditionally, when calculating percentage heights, browsers have interpreted the spec's use of the term "height" to mean the value of the
height property. It could just as easily be interpreted as a height (generic term), but the
height property requirement has become the predominant implementation. I've never seen
max-height work on a parent when dealing with percentage heights.
It's not clear which browser is more compliant.
It doesn't help matters that the
height property definition hasn't been updated since 1998 (CSS2).
Instead of defining the height of
flex: 1 1 0%, try using
height: 100% or
height: calc(100% - 60px) or absolute positioning.