Child's `height: 100%;` is not taking parent's full height, why?

Viewed 4619

Both parent and child have box-sizing: border-box;. According to MDN:

<percentage> Defines the height as a percentage of the containing block's height.

Then the child's height should be 500px as well, but obviously it's not, it has the height of the parent's content height, not parent's height. Having tried this code on many browsers including IE, they all work the same, why is that?

<!DOCTYPE html>
<html lang="zh-Hans">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css" />
    <title>Test</title>
    <style>
      body {
        background: #000;
      }
      .parent {
        border: 50px solid blue;
        padding: 20px;
        width: 500px;
        height: 500px;
        background: green;
        overflow: auto;
      }
      .child {
        background: red;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
4 Answers

Using border-box just defines how the given height should apply with respect to padding and border values. In your example this results in a outer height of 500px for .parent.

Basically it's just a convenience method - so that you don't have to calculate the actual height yourself (as in the times before border-box was a thing). Without it, you'd need to define height: 360px; to achieve an outer height of 500px.

But .child's containing block still resides inside the area delimited by .parent's padding. And percentage heights are calculated with respect to that containing block (ref). Which in this example are the same 360px you would have used without border-box on .parent.

this is, as you can see, because you have set a padding to the parent. so its 100% will not take padding into account.

body {
   background: #000;
}
.parent {
   border: 50px solid blue;
   padding: 20px;
   width: 500px;
   height: 500px;
   background: green;
   overflow: auto;
}
.child {
   background: red;
   height: 100%;
}
<div class="parent">
  <div class="child"></div>
</div>

it is not clear what you are trying to do, but if you want to make the child fill the entire parent a solution could be this:

body {
   background: #000;
}
.parent {
   border: 50px solid blue;
   /* padding: 20px; simply remove the padding */
   width: 500px;
   height: 500px;
   background: green;
   overflow: auto;
}
.child {
   background: red;
   height: 100%;
}
<div class="parent">
  <div class="child"></div>
</div>

this is because when the property box-sizing is set to border-box the padding becomes to being taken into account from the properties height, width... but this doesn't mean that the padding disappears, the padding is simply acts on the content of the parent.

remember this!
content

Looks like I misunderstood the term containing block, I thought it would be the parent, but not really, there's much more into this.

I had to dig into the W3C standard to find out:

Definition of "containing block"

The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element.

The containing block in which the root element lives is a rectangle called the initial containing block.

For other elements, if the element's position is 'relative' or 'static', the containing block is formed by the content edge of the nearest block container ancestor box.
...

Because You use child div in Parent and Parent height is 500px and You use child height 100 % That's why child get 500px Height due to parent.

Related