10

I have a flexbox with a direct child that is declared with align-items: stretch.

Inside this flexbox's direct child, I would like to have a div container that also uses its parent's full height (by setting height: 100%).

However, the div container won't stretch to 100% height of its parent, unless I also set height: 100% on the flexbox's direct child.

Is it kind of bug? Must I set the flexbox's direct child with align-items: stretch AND height: 100% to achieve what I want? It seem redundant to me.

Here is an example:

html,
body {
  margin: 0;
  height: 100%;
}

.flexbox {
  display: flex;
  flex-direction: row;
  height: 100%;
  background-color: green;
}

.flexbox-child {
  // height: 100%; uncommenting this will get it to work
  align-items: stretch;
  background-color: blue;
}

.flexbox-grand-child {
  height: 100%;
  background-color: red;
}
<div class="flexbox">
  <div class="flexbox-child">
    <div class="flexbox-grand-child">
      I want to be stretched till the bottom
    </div>
  </div>
</div>

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

Thanks!

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
gipouf
  • 1,221
  • 3
  • 15
  • 43

2 Answers2

8

It's a complicated case.

Your .flexbox-child is only a flex item, but not a flex container. Therefore, align-items: stretch, which only applies to flex containers, is ignored.

Then, .flexbox-grand-child has a percentage height, which behaves like this:

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 (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.

The containing block is the flex item (.flexbox-child), which has no explicit height, and its height seems to depend on the content.

However, this dependency is only due to the new min-height: auto. But before taking min-height into account, the height of the flex item will be (due to the initial align-self: stretch) the height of the container, which is specified explicitly, ignoring the content.

Then, Firefox considers that the height of .flexbox-child does not depend on its contents, so height percentages in its children should work. And then your code works.

However, Chrome doesn't think so.

I'm not sure which one does it right. It doesn't help that height is only defined in the old CSS2.1 and in CSS basic box model, which is an inconsistent draft.

To be safe, better set the height of .flexbox-child explicitly. Or make it a flex container.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Yeah, I'd say you got that backwards, the bug is in FF. Percentage heights only should work when the height is "specified explicitly". Imho being a stretched flex items doesn't qualify. [Example fiddle](http://jsfiddle.net/woestijnrog/nbx92s5a/) – woestijnrog Oct 31 '15 at 23:20
  • @woestijnrog Yes, but Firefox's behavior might still make sense. See my update. – Oriol Oct 31 '15 at 23:26
  • Thanks for the detailed answer. Btw, what do you mean by "the new min-height: auto"? – gipouf Oct 31 '15 at 23:32
  • 2
    @royv Previously, the initial value of `min-height` and `min-width` was `0`. However, the flexbox spec changes it to `auto`. `auto` behaves like `0` for most elements. However, for flex items with `overflow: visible`, it forces them to grow to cover their contents. See [Implied Minimum Size of Flex Items](http://www.w3.org/TR/css-flexbox-1/#min-size-auto) – Oriol Oct 31 '15 at 23:58
  • 2
    I'm wondering if the spec has changed. Both FF(49) and Chrome(53) seem to have no issues making children of flex items be 100% height. But Safari (10) can't handle it and a specific height needs to be set on the flex item for children to stretch correctly. – gman Sep 28 '16 at 14:47
  • @gman The spec has been reworded but I think this was already standard when I wrote this. Since the flex item is stretched, its height is considered definite (see [Definite and Indefinite Sizes](https://www.w3.org/TR/css-flexbox-1/#definite-sizes)), so the percentage should work. It was only a problem with Chrome's implementation, which has been fixed. – Oriol Sep 28 '16 at 15:06
  • Except it's not fixed in Safari AFAIK :( Works in FF, Works in Chrome, Does not work in Safari https://jsfiddle.net/greggman/Lz2yppab/ – gman Sep 28 '16 at 15:19
8

When you create a flex container only the child elements become flex items. Descendants beyond the children do not become flex items and flex properties don't apply to them.

Simply apply display: flex to the flex item, which converts it into a flex container, as well. Then default flex properties like align-items: stretch will apply to the children (now flex items).

You wrote:

I would like to have a div container that also uses its parent's full height...

You don't need to use height: 100% or add align-items: stretch (it's a default rule). Simply add display: flex to .flexbox-child, and .flexbox-grand-child will expand the full available height.

Modified demo: http://plnkr.co/edit/n0Wt3x3CUr1ZfBD2RrGo?p=preview


re: height: 100% possible bug

With regard to the need to specify height: 100% on child elements, I don't see any bug here. Everything seems to conform to the spec. Here's a complete explanation: Working with the CSS height property and percentage values

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