1

I still have troubles to understand how elements choose their containing block, with respect to which their relative values of e.g. height are evaluated.

body {
  margin: 0;
}

.outer {
  min-height: 200px;
  background: red;
  overflow: hidden;
}

.inner {
  height: 100%;
  background: green;
}
<div class="outer">
  Hello,
  <div class="inner">world!</div>
</div>

Here the outer container has only a min-height set, which is apparently not enough to assert itself as containing block, even with overflow hidden.

My understanding was that without overflow hidden, there is a cyclic dependency, as the parent size depends on the child size when the child is higher than 200 px, but with overflow hidden that cyclic dependency should be gone.

What's even weirder, it starts 'working' again when I set the body to display flex.

body {
  display: flex;
  flex-direction: column;
  height: 100vh;
  margin: 0;
}
.outer {
  min-height: 200px;
  background: red;
  overflow: hidden;
}

.inner {
  height: 100%;
  background: green;
}
<div class="outer">
  Hello,
  <div class="inner">world!</div>
</div>

What is the logic behind that?

fweth
  • 631
  • 6
  • 16
  • *Here the outer container has only a min-height set, which is apparently not enough to establish a BFC, even with overflow hidden.* --> what makes you think there is no BFC? it does create a BFC – Temani Afif Nov 16 '21 at 12:25
  • I think you are confusing two orthogonal features. BFC and percentage height have no relation between each other – Temani Afif Nov 16 '21 at 12:26
  • Ah sorry, yes that is true! I thought BFC is what percentage values compare against. – fweth Nov 16 '21 at 12:54
  • I changed it from BFC to containing block, I hope this is the right terminology? – fweth Nov 23 '21 at 09:05

1 Answers1

2

First, the containing block in both cases is the same for inner and it's outer. overflow play no role here, same for the usage of flexbox. More detail: https://www.w3.org/TR/CSS2/visudet.html#containing-block-details

Now, you need to understand the trickery around percentage height. The general rule is: "the containing block need to have an explicit height"

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

Considering this, you can assume that your percentage height will fail in both cases BUT things have changed and now we can resolve percentage height in some particular cases where we don't have any explicit height defined on the containing block.

Sometimes the size of a percentage-sized box’s containing block depends on the intrinsic size contribution of the box itself, creating a cyclic dependency. When calculating the intrinsic size contribution of such a box (including any calculations for a content-based automatic minimum size), a percentage value that resolves against a size in the same axis as the intrinsic size contribution (a cyclic percentage size) is resolved specially: ref

If you keep reading, you will find a lot of complex concept and definition not easy to understand. I will not detail all of them but your second case is one of them.

To make it easy: Flexbox force some sizes to be definite allowing percentage height to be resolved (https://drafts.csswg.org/css-flexbox-1/#definite-sizes).

There are more cases like that related to flexbox and CSS grid as well:

Percentage 'min-height' works only when element has indirect parent with 'display: flex'

Why does `height: 100%` value 'work' for child tags of grid-items?

https://stackoverflow.com/a/52137966/8620333

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks a lot for the answer! You are right, overflow hidden makes no difference in this case. But there are some cases where it makes a difference, like [here](https://jsfiddle.net/gpw0feut/1/). Without overflow hidden, the image would not contain itself in the space left remaining above the title. – fweth Nov 23 '21 at 09:38
  • @fweth that is another story and you should use min-height: 0; instead of overflow. You are facing the min-height default constraint and overflow is one way to disable it (https://stackoverflow.com/q/36247140/8620333). And it's not related to containing block or percentage height – Temani Afif Nov 23 '21 at 09:46
  • Sorry for the late interruption, just one question, do I understand this correctly that the new [specification](https://drafts.csswg.org/css-sizing-3/#percentage-sizing) states just "Percentages specify sizing of a box with respect to the box’s containing block" without the clause for the height of the parent needing to be explicitly specified? – fweth Sep 06 '22 at 17:40
  • 1
    @fweth yes, as I explained in my answer, now some percentage height can be resolved even if the parent doesn't have an explicit height but still in some cases it will fail to auto so it's logical to remove it from the Spec because it's not more true for all the cases – Temani Afif Sep 06 '22 at 17:49