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.
#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:
#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.