Home > Enterprise >  Problem with max-height not working in css grid element
Problem with max-height not working in css grid element

Time:12-03

I have a problem with max-height not working properly in grid elements. Basically I have a grid element with flexible size, and within it I am showing an iframe. I want to scale the iframe to its full size, and have a surrounding div which fits to the iframe size, with a maximum size equal to the grid element, and from there scroll. My problem is, that max-height somehow does not work properly. I prepared a jsfiddle for this:

For this code I get different results for using "height: 100%;" or "max-height: 100%" in #grid1:

#grid0 {
  display: grid;
  grid-template-rows: 50px;
  grid-template-columns: 200px;
  height: 500px;
}

#grid1 {
  height: fit-content;
  max-height: 100%;
  background: blue;
  /* it works using height instead of max-height
  height: 100%;
  */
}

#out {
  height: auto;
  max-height: 100%;
  overflow: hidden;
  background: purple;
  width: 150px;
}

#large {
  height: 100px;
  width: 100px;
  background: red;
}
<div id='grid0'>
  <div id='grid1'>
    <div id='out'>
      <div id='large'>
      </div>
    </div>
  </div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Compare the results between this and commenting in the "height: 100%;"-line in the css for #grid1. Interestingly when inspecting #grid1 with firefox its height gets shown as it should be even with max-width, but clearly it is not rendered this way.

I tried to introduce another container around #out, set its height to auto and max-height to 100% and #grid1's height to 100% fix, because I thought it might be the "fit-content", but it did not work either...

Does anyone have suggestions how to get around this, or am I doing something wrong?

I would be happy about every hint!

CodePudding user response:

I think the issue not actually related to the grid. I can reproduce it using normal block element as well.

Show code snippet

#div0 {
  width: 200px;
  height: 50px;
}

#div1 {
  height: fit-content;
  max-height: 100%;
  background: blue;
  /* it works using height instead of max-height
  height: 100%;
  */
}

#out {
  height: auto;
  max-height: 100%;
  overflow: hidden;
  background: purple;
  width: 150px;
}

#large {
  height: 100px;
  width: 100px;
  background: red;
}
<div id='div0'>
  <div id='div1'>
    <div id='out'>
      <div id='large'>
      </div>
    </div>
  </div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

My explanation is based on following specs:

Percentages specify sizing of a box with respect to the box’s containing block.ref

Intrinsic sizing determines sizes based on the contents of an element, without regard for its context.

That is using min-content, max-content, and fit-content values.


In your case #grid1(blue) is working as expected it is getting 50px height because of max-height: 100%. height:fit-content has no effect, if it did then blue would be 100px high.

The problem is that #out(purple) is overflowing. It is because the container blue is saying my height is dependent on my children(because of fit-content). When you set height:100% you say it's height is dependent on container #grid0 and not #out(purple). When both #grid1(blue) and #out(purple) purple say they depend on each other then it creates a cyclic dependency.

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 the box is non-replaced, then the entire value of any max size property or preferred size property (width/max-width/height/max-height) specified as an expression containing a percentage (such as 10% or calc(10px 0%)) that is cyclic is treated for the purpose of calculating the box’s intrinsic size contributions only as that property’s initial value. For example, given a box with width: calc(20px 50%), its max-content contribution is calculated as if its width were auto.

That means percentage heights are treated as auto on purple. So it relies on it's children #large for height. As large has 100px height purple gets 100px height as well.


You said you added one more container around #out:

Show code snippet

#div0 {
  width: 200px;
  height: 50px;
}

#div1 {
  max-height: 100%;
  background: blue;
  /* it works using height instead of max-height*/
  height: 100%;
}

#div2 {
  height: auto;
  /* uncomment following to get desired result */
  /* height: inherit;*/
  max-height: 100%;
}

#out {
  height: auto;
  max-height: 100%;
  overflow: hidden;
  background: purple;
  width: 150px;
}

#large {
  height: 100px;
  width: 100px;
  background: red;
}
<div id='div0'>
  <div id='div1'>
    <div id="div2">
      <div id='out'>
        <div id='large'>
        </div>
      </div>
    </div>
  </div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

In this code if you use inherit instead of auto it fixes the issue. Inherit makes it dependent on parent and auto on children.

  • Related