5

I'm trying to check how CSS 100% height property works. But there's one thing I can't understand.

Why's 100% height working perfectly on .flex-grand-child (Chrome)? Does .flex-child have height property? So why it's even working???

Here's JSFiddle

html, body {
  height: 100%;
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.flex-parent {
  flex: 1 0 auto;
  display: flex;
}

.flex-child {
    width: 300px;
}

.flex-grand-child {
   height: 100%;
   background-color: green;
}
<div class="container">
    <div class="flex-parent">
        <div class="flex-child">
          <div class='flex-grand-child'></div>
        </div>
    </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701

3 Answers3

1

This is a particular case where the browser can handle percentage value on height due to the stretch effect of flexbox. The flex-child has a default alignment equal to stretch which is equivalent to having height:100% then the flex-parent is also filling its parent height with flex-grow:1. At the end, the browser was able to correctly resolve the height:100% of flex-grand-child

If the flex item has align-self: stretch, redo layout for its contents, treating this used size as its definite cross size so that percentage-sized children can be resolved.ref

If you disable the stretch alignment, it will break:

html,
body {
  height: 100%;
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.flex-parent {
  flex: 1 0 auto;
  display: flex;
}

.flex-child {
  width: 300px;
  min-height: 200px;
  align-self: flex-start; /*this will break it*/
  border: 1px solid;
}

.flex-grand-child {
  height: 100%;
  background-color: green;
}
<div class="container">
  <div class="flex-parent">
    <div class="flex-child">
      <div class='flex-grand-child'></div>
    </div>
  </div>
</div>

To use simple words: When having the stretch effect, the browser will first define the parent height based on its own parent (the content play no role here) then the browser will make the content height:100% of the previous calculated height. Without stretch the browser need to consider the content to define the height of the parent and here we will fall into the classic issue of percentage height.


Related question to get more cases where percentage can be resolved without having an explicit height defined on the parent element: Why is my Grid element's height not being calculated correctly?

Here is the relevant part of the specification dealing with this: https://www.w3.org/TR/css-sizing-3/#percentage-sizing

It's a bit complex but it's different from the CSS2 specification where percentage will always fail if the parent height is not specified:

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

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
0

The .flex-parent element has flex-grow: 1 applied, giving it the full height of the .container (height: 100%). It also has display: flex applied, making it a flex container.

This latter setting automatically triggers align-items: stretch, which causes the flex item – .flex-child – to expand the full height of the container. So the .flex-child computes to height: 100%.

Modern browsers, now accepting flex heights as a reference point for children with percentage heights, set the child of the flex item – .flex-grand-child – to the full height of the parent, which is height: 100%.

More details here: Chrome / Safari not filling 100% height of flex parent

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

You have .container as a flex container with a flex-direction of column, so by default, the child element will stretch to fill. So .flex-parent is stretching to fill .container.

Since .flex-parent is also a flex-container, .flex-child is stretching to fill that.

Finally, since .flex-grand-child has height 100%, it is also filling the entire area.

aprouja1
  • 1,800
  • 8
  • 17