4

I was going through this doc about containing blocks. Note the Example 2 here.

HTML:

<body>
  <section>
    <p>This is a paragraph!</p>
  </section>
</body>

CSS:

body {
  background: beige;
}

section {
  display: inline;
  background: lightgray;
}

p {
  width: 50%;     /* == half the body's width */
  height: 200px;  /* Note: a percentage would be 0 */
  background: cyan;
}

In the CSS inline comment, it states that a percentage would be 0. Why is this the case?

My understanding has been that a block element's height would be the height of its content unless explicitly set. Can someone clarify why a percentage of the height would be zero and also, if my understanding is wrong?

Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
Black Wind
  • 313
  • 1
  • 8

1 Answers1

3

In CSS, percentage-based sizes are relative to the parent of the element. The parent must also have a fixed (read: non-percentage) size.

In this case, body has no defined height, and so you get this:

body {
  background: beige;
}

section {
  display: inline;
  background: lightgray;
}

p {
  width: 50%;
  height: 100%; 
  background: cyan;
}
<body>
  <section>
    <p></p>
  </section>
</body>

You can test this by giving body or section a fixed size and seeing the result:

body {
  background: beige;
  height: 250px;
}

section {
  display: inline;
  background: lightgray;
}

p {
  width: 50%; 
  height: 100%;
  background: cyan;
}
<body>
  <section>
    <p></p>
  </section>
</body>

The cyan box now takes up 100% of the value of the height of body.

One of the workarounds that you will often see used for this scenario is that people will give the top-level container a size relative to the viewport. If we give body, say, height: 50vh, and then give p a height of 100%, even though viewport height is a scalar/percentage based unit, it will resolve as you would desire.

body {
  background: beige;
  height: 50vh;
}

section {
  display: inline;
  background: lightgray;
}

p {
  width: 50%;  
  height: 100%; 
  background: cyan;
}
<body>
  <section>
    <p></p>
  </section>
</body>

However, because you have content inside of your <p> element, a percentage-based height would not resolve to zero. I believe the comment in the original example was made to illustrate the fact that a percentage-based height would not increase the height beyond the native size of the <p> and its contents, but could have been phrased slightly better to say something along these lines.

loomy
  • 361
  • 1
  • 5
  • 1
    I'm not sure this answers the OP's question; they seem to be aware of the information you're providing in your answer. Their question is specifically why `height: 200px` should be understood as _zero_ per the comment from MDN (unless I'm misunderstanding their intent). – Alexander Nied Aug 15 '22 at 04:33
  • Oh, I think you are actually correct. I have amended my answer to explain this part of their question as well. Thank you! – loomy Aug 15 '22 at 04:41
  • 1
    @loomy thank you for the detailed answer. However, can you tell me why the background color `beige` fills the whole screen in all the examples? Even when you have explicitly mentioned that the `height` value for `body` is `250px`, the background color extends to the whole screen. Note, I am viewing this on Firefox. – Black Wind Aug 15 '22 at 06:15
  • No problem! There is actually a very interesting explanation for this, and surprisingly, it is one of the rare exceptions where a child element communicates with its parent. [Check out this previously answered question for a good explanation.](https://stackoverflow.com/a/5225321/19747009) – loomy Aug 15 '22 at 06:23
  • Here is an answer to my question above: [link](https://stackoverflow.com/questions/5225237/why-does-styling-the-background-of-the-body-element-affect-the-entire-screen). Update: I see that @loomy has already posted this answer. – Black Wind Aug 15 '22 at 07:08