Flexbox in Chrome--How to limit size of nested elements? [duplicate]


Tags: html,css,css3,google-chrome,flexbox

Problem :

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

http://plnkr.co/edit/UBRcrNmR5iDbn3EXu6FI?p=preview

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.)



Solution :

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.

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.

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 height: 100vh.

One level down, .max-flex (level 2) has height: 100%.

Four levels down, .large-nested-div (level 4) has height: 100%.

However, at .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 auto.


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 min-height or max-height work on a parent when dealing with percentage heights.

Recently, however, as noted in this question and another one and another one, Firefox has broadened its interpretation to accept flex heights, as well.

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).


The Solution

Instead of defining the height of .variable-flex-content with flex: 1 1 0%, try using height: 100% or height: calc(100% - 60px) or absolute positioning.


    CSS Howto..

    How can I make a split-text input placeholder?

    jQuery: How to change the size of a css block?

    How do I make this carousel implementation better?

    How to change dropdown submenu second level background?​

    How to put a div in more pages

    How to get the CSS left, top, width, height from coords?

    How to increase the width size of JQuery UI Tooltip by its default value?

    CSS How to hide current child menu items when hovering over parent's sibling items without javascript

    How to use jQuery to check if element breaks to the next line?

    How do I stop richfaces adding borders to panels and calendars?

    How to make CSS border on an image? [closed]

    How to completely gray out an image with css?

    Parsley.js 2.0 How to use the provided css file

    How do I change a specific css element with javascript?

    How can I change the color of this text?

    How do I style HTML in a JEditorPane?

    How to use bootstrap grid system overlaying a map

    how to change the position of these links within div header

    How to apply the grayscale jquery plugin to a background image?

    How to move an image up and down smoothly with CSS?

    How to switch tabs and change css class on click using Angular2?

    How to trigger a modal view with Highcharts, when zoom is also enabled?

    How do I remove the text underline (that I set myself) from a on hover?

    how to position a container in the middle of the screen? [duplicate]

    How to display 3 buttons on the same line in css

    How to create custom archive page on Tumblr

    How to scroll left column when cursor is above right column?

    how to set div display property block when url have some id?

    Only show one hidden table row at a time

    How to make an oblique oval in CSS?