Dealing with cyclic dependencies of percentage sized boxes css (specifically how to get a max-height)


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>

Source: CSS – Stack Overflow

December 3, 2021
Category : News
Tags: css | cyclic-dependency

Leave a Reply

Your email address will not be published. Required fields are marked *

Sitemap | Terms | Privacy | Cookies | Advertising

Senior Software Developer

Creator of @LzoMedia I am a backend software developer based in London who likes beautiful code and has an adherence to standards & love's open-source.