4

I'm using Bootstrap 4 for simplicity.

My questions are:

  1. Why setting 100% height on child (.inner) of flex item works? For every element in this code height is "set" to auto.
  2. How .inner elements know that 100% height is the height of the heighest flex child (.col-4) in a row?

CODEPEN

HTML:

<div class="container">
  <h3>Without 100% height on inner elements</h3>
  <div class="row">
    <div class="col-4">
      <div class="inner">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div class="col-4">
      <div class="inner">Inner</div>
    </div>
    <div class="col-4">
      <div class="inner">Inner</div>
    </div>
    <div class="col-4">
      <div class="inner">Inner</div>
    </div>
    <div class="col-4">
      <div class="inner">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</div>
    </div>
  </div>
</div>

<div class="container">
  <h3>With 100% height on inner elements</h3>
  <div class="row">
    <div class="col-4">
      <div class="inner h-100">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div class="col-4">
      <div class="inner h-100">Inner</div>
    </div>
    <div class="col-4">
      <div class="inner h-100">Inner</div>
    </div>
    <div class="col-4">
      <div class="inner h-100">Inner</div>
    </div>
    <div class="col-4">
      <div class="inner h-100">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</div>
    </div>
  </div>
</div>

CSS:

.inner {
  background: #ddd;
}
h-100 {
  height: 100%;
}
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
max
  • 8,632
  • 3
  • 21
  • 55

1 Answers1

2

Why setting 100% height on child (.inner) of flex item works? For every element in this code height is "set" to auto.

Since the beginnings of CSS in the 1990s, a percentage height on an in-flow child element has required a defined height on the parent element. Otherwise the child defaults to height: auto.

The only acceptable height reference on the parent has come from the height property. Other forms of height, such as min-height and max-height, have been invalid for this purpose.

Although the spec has never explicitly specified that the parent must use the height property – only the generic work "height" has been used – using the height property has become the traditional interpretation and predominant implementation across browsers.

In recent years, however, browsers have broadened their interpretation of spec language to include other forms of height, such as flex-basis.

So, in 2017, it's not surprising that height: 100% does not resolve to height: auto in all cases where the parent has no specified height.

Today's browsers may also seek a height reference from flex-grow, flex-basis, align-items or something else.

Here a some more details about the height property and percentage values:

And then there are interventions:

An intervention is when a user agent decides to deviate slightly from a standardized behavior in order to provide a greatly enhanced user experience.

This is browsers makers basically saying: "Thanks for the spec guidance, but we know our users and we can do better." So they go off-script hoping to be more thoughtful and intuitive.

Here are several examples of possible Chrome interventions:

So, between interventions and a broader interpretation of the rules, height: 100% may give full height even when the parent has no height defined.

How do .inner elements know that 100% height is the height of the highest flex child (.col-4) in a row?

They don't. They just stretch to the height of the container, who's height is set by the tallest item in the row.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    Thank you for such a detailed answer. I'll try to understand it with your recommendations. Do you know maybe if it's consistent across different browsers? – max Nov 28 '17 at 01:11
  • 1
    I tested in Chrome (v62), Firefox (v57) and Edge (v16), and got the exact same behavior. Don't know about Safari or other browsers. – Michael Benjamin Nov 28 '17 at 01:14
  • Great, thanks. I also removed all flex properties on flex items (grow, shrink, basis) so it seems like `display: flex` is enough to be able to use percentage height on these elements. – max Nov 28 '17 at 01:18
  • 1
    Well, keep in mind that with `display: flex`, an initial setting is `align-items: stretch`, which automatically sets all children to the height of the container -- the source of the flex *equal height columns* feature. This feature is disabled when you define a height on a flex item. – Michael Benjamin Nov 28 '17 at 01:37
  • True. Unfortunately this solution doesn't work on Safari (Mac). I'm looking for that feature because I want to have equal height columns and in the same time gaps between them. If I set a background to `col` divs gaps won't be visible. And also I can't use margin instead of padding on `col` class divs. I know that I can for example set columns width to 30% and gaps will be there if I use `space-between` but I'm looking for simple solution to incorporate it with Bootstrap grid system. – max Nov 28 '17 at 01:53
  • You should post a new question with the actual problem. There may be a simple solution. – Michael Benjamin Nov 28 '17 at 01:54