I'm struggling with what seems should very much be a beginner task in CSS: scrolling and heights (when elements are nested more than 1 level deep).
I'd like to design layouts where default elements do not expand past their parent elements, and if they do, overflow: auto kicks in and they start scrolling.
I don't want to set height; 100% on every element though, as I need elements to only take up the space required, and so have been trying to use instead max-height: 100% or max-height: inherit on every element.
When using height: 100%, the height of the parent is correctly picked up even when elements are nested several layers deep, as seen here: Code Pen 1
html {
padding: 0;
margin: 0;
overflow: hidden;
}
body {
height: 95vh;
background-color: red;
overflow: hidden;
}
.levelOne {
background-color: blue;
height: 100%;
/* Correctly gets parent height */
}
.levelTwo {
background-color: green;
overflow: auto;
height: 100%;
/* Correctly gets grand-parent height */
}
<div class="levelOne">
<div class=levelTwo>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
</div>
</div>
When attempting to not overflow a nested div with max-height: 100% however, it appears that the level 1 child correctly stops at the parent height, but a level 2 child will spill out. Code Pen 2
*,
*:before,
*:after {
box-sizing: inherit;
max-height: inherit;
overflow: hidden;
}
html {
padding: 0;
margin: 0;
overflow: hidden;
}
body {
height: 95vh;
background-color: red;
overflow: hidden;
}
.levelOne {
background-color: blue;
max-height: 100%;
/* Correctly gets parent height*/
}
.levelTwo {
background-color: green;
overflow: auto;
max-height: 100%;
/* DOESN'T get grandparent hight, but spills out of levelOne so overflow: auto never starts to scroll; */
}
<div class="levelOne">
<div class=levelTwo>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
<p>Lorem</p>
</div>
</div>
- Why does
max-height: 100%not top out at the grandparent's height, while `height: 100%' does? I would have expected similar behavior. - Is there a better method to not allow elements to spill out of their parent sizes?
I have also seen a recommendation to do something like the following, but if max-hight isn't able to calculate past the 1st layer deep, it fails too:
*, *:before, *:after {
box-sizing: inherit;
max-height: inherit;
overflow: hidden;
}
It seem like for some reason if the divs are a 1x1 css grid things work more consistently at deeper levels, but sometimes a grid is too much overhead, and I'm hoping to better understand the basics.
Thank you.