First shortly, this is a follow up question to Problem with max-height not working in css grid element where I misunderstood my problem and I would have had to completely rewrite it, so I'm starting a new one, I hope that is fine.
My goal in one sentence is, to have an overflow: auto
in a box, which has its height governed by its content, but its max-height governed by its parent. A static representation would be:
#ctlsmall {
height: 50px;
}
#ctlbig {
height: 210px;
}
#contentsmall {
height: 50px;
}
#contentbig {
height: 350px;
}
.content {
background-image: linear-gradient(30deg, #005500 0%, #9922ee 100%);
width: 120px;
}
.overflowctl {
overflow-y: auto;
overflow-x: hidden;
}
.frame {
height: auto;
max-height: calc( 100% - 40px );
width: 120px;
border-radius: 15px;
padding: 20px;
background: #221100;
}
.canvas {
display: inline-block;
height: 250px;
width: 200px;
margin-right: 50px;
background: #ddccaa;
vertical-align: top;
}
<div class='canvas'>
<div class='frame'>
<div id='ctlbig' class='overflowctl'>
<div id='contentbig' class='content'>
</div>
</div>
</div>
</div>
<div class='canvas'>
<div class='frame'>
<div id='ctlsmall' class='overflowctl'>
<div id='contentsmall' class='content'>
</div>
</div>
</div>
</div>
The problems begin, when I don't want to use fix heights for my .overflowctl
, because both, .content
and .canvas
have unknown sizes. (.content
in reality is an iframe, and .canvas
depends on the window size). My naive approach was to just use height: auto
for .overflowctl
and .frame
, as usually the height should be governed by their content, and at the same time a percentage based max-height, as their max-height is set by the parents. This is logical in a natural understanding of those properties, but seemingly it does not work, because in css the combination between a parent-child combination, where the parent size relies on the child and vice versa is problematic and while solving this, the max-properties seem to be changed... It is described here and @onkar-ruikar who showed this to me as an answer to my previous question gave some explanation for it. I prepared a jsfiddle to illustrate the problem, with the adapted example from above:
.overflowctl {
height: auto;
max-height: 100%;
}
#contentsmall {
height: 50px;
}
#contentbig {
height: 350px;
}
.content {
background-image: linear-gradient(30deg, #005500 0%, #9922ee 100%);
width: 120px;
}
.overflowctl {
overflow-y: auto;
overflow-x: hidden;
}
.frame {
height: auto;
max-height: calc( 100% - 40px );
width: 120px;
border-radius: 15px;
padding: 20px;
background: #221100;
}
.canvas {
display: inline-block;
height: 250px;
width: 200px;
margin-right: 50px;
background: #ddccaa;
vertical-align: top;
}
<div class='canvas'>
<div class='frame'>
<div id='ctlbig' class='overflowctl'>
<div id='contentbig' class='content'>
</div>
</div>
</div>
</div>
<div class='canvas'>
<div class='frame'>
<div id='ctlsmall' class='overflowctl'>
<div id='contentsmall' class='content'>
</div>
</div>
</div>
</div>
In my previous question, I somehow had an example where height and max-height worked differently, but I think the above better shows what I actually want, and the problem boils down to the same thing. The ugly solution would be, to get rid of the .overflowctl
, but then my nice .frame
(in reality the colors are better...^^) doesn't work anymore with the padding and also the combination of scroll bar and border-radius. I will add it at the end, just to show it, anyways. I would be happy about any hints how I can achieve my goal! :)
#contentsmall {
height: 50px;
}
#contentbig {
height: 350px;
}
.content {
background-image: linear-gradient(30deg, #005500 0%, #9922ee 100%);
width: 120px;
}
.frame {
overflow-y: auto;
overflow-x: hidden;
}
.frame {
height: auto;
max-height: calc( 100% - 40px );
width: 120px;
border-radius: 15px;
padding: 20px;
background: #221100;
}
.canvas {
display: inline-block;
height: 250px;
width: 200px;
margin-right: 50px;
background: #ddccaa;
vertical-align: top;
}
<div class='canvas'>
<div class='frame'>
<div id='contentbig' class='content'>
</div>
</div>
</div>
<div class='canvas'>
<div class='frame'>
<div id='contentsmall' class='content'>
</div>
</div>
</div>
Simply add this
.frame {
display:grid;
grid-template-rows:1fr;
}
This will give a reference for your percentage height.
Full code
.overflowctl {
height: auto;
max-height: 100%;
}
#contentsmall {
height: 50px;
}
#contentbig {
height: 350px;
}
.content {
background-image: linear-gradient(30deg, #005500 0%, #9922ee 100%);
width: 120px;
}
.overflowctl {
overflow-y: auto;
overflow-x: hidden;
}
.frame {
height: auto;
max-height: calc( 100% - 40px );
width: 120px;
border-radius: 15px;
padding: 20px;
background: #221100;
display:grid;
grid-template-rows:1fr;
}
.canvas {
display: inline-block;
height: 250px;
width: 200px;
margin-right: 50px;
background: #ddccaa;
vertical-align: top;
}
<div class='canvas'>
<div class='frame'>
<div id='ctlbig' class='overflowctl'>
<div id='contentbig' class='content'>
</div>
</div>
</div>
</div>
<div class='canvas'>
<div class='frame'>
<div id='ctlsmall' class='overflowctl'>
<div id='contentsmall' class='content'>
</div>
</div>
</div>
</div>
CSS grid and Flexbox have some special behavior related to percentage height.
Related questions to get more details:
Why does `height: 100%` value 'work' for child tags of grid-items?
Percentage 'min-height' works only when element has indirect parent with 'display: flex'