Child With Max-Height: 100% Overflows Parent

Child with max-height: 100% overflows parent

When you specify a percentage for max-height on a child, it is a percentage of the parent's actual height, not the parent's max-height, oddly enough. The same applies to max-width.

So, when you don't specify an explicit height on the parent, then there's no base height for the child's max-height to be calculated from, so max-height computes to none, allowing the child to be as tall as possible. The only other constraint acting on the child now is the max-width of its parent, and since the image itself is taller than it is wide, it overflows the container's height downwards, in order to maintain its aspect ratio while still being as large as possible overall.

When you do specify an explicit height for the parent, then the child knows it has to be at most 100% of that explicit height. That allows it to be constrained to the parent's height (while still maintaining its aspect ratio).

Why CSS height 100% overflow parent?

#black does not have a height (it has a max-height).

Therefore, all other height or max-height or 100% is ignored, because 100% on unknown is unknown.

The only reason #red has a height is because it's child - #grey - has a height of 100px

Change max-height: 50px to height: 50px on #black and you'll see everything work exactly as it should:

#black {  background-color: black;  padding: 5px;  height:50px;}
#red { background-color: red; padding: 5px; height:100%;}
#grey { background-color: grey; height: 100px; /* The height is just used as an exemple, it cannot be known. */ max-height: 100%;}
<div id="black">    <div id="red">      <div id="grey"></div>    </div></div>

Why is height: 100%; overflowing parent?

I would convert to a simple flexbox layout.

#root {
width: 500px;
height: 100px; /* 300px; */
border: 1px solid black;
display: flex;
flex-direction: column;
}

#header {
border-bottom: 1px solid black;
}

#content {
flex: auto;
border-bottom: 1px solid red;
}
<div id="root">
<div id="header">Some content</div>
<div id="content">Why am I overflowing ?</div>
</div>

restrict child div height to parent container height

The overflow you see happens because there is already an element taking up some space of the parent, so height: 100% plus the height of the other element will obviously exceed the parents height.

There are different ways to solve the problem.

I recommend one of these two ways:

  • CSS Flexbox
  • CSS Grid

However, you can also solve them using these ways:

  • CSS calc()
  • JavaScript

CSS Flexbox

The parent needs display: flex and flex-direction: column to lay out its children in a column.

The child that should grow to take up the remaining space needs flex-grow: 1.

/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}

/* The answer */
.graph-container {
height: 60vh;
width: 70vw;

display: flex;
flex-flow: column; /* Shorthand for ('flex-direction' | 'flex-wrap') */
}
.graph {
flex-grow: 1;
border-color: red;
}
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>

CSS grid child with height 100% overflows parent

Don't use height: 100%. The 100% isn't relative to the parent, because you haven't defined a height on the parent. So ask yourself: "100% of what?". Without specific guidance (i.e., an explicit height on the parent), browser behavior is unreliable and may vary.

Just avoid the extra complication of percentage heights and use flex properties all the way through.

.grid {  display: grid;  grid-template-columns: 1fr 1fr 1fr;  grid-template-rows: 1fr;}
/* enables flex properties on the child */.grid__item { display: flex; flex-direction: column;}
.grid__inner-content { flex: 1; /* consumes all free space (taking full height) */ display: flex; flex-direction: column; justify-content: space-between; /* height: 100%; */}
<div class="grid">  <div class="grid__item">    Stuff 1    <div class="grid__inner-content">      <ul class="page-marketing__list">        <li>Website template design, 1 of 7 templates without a blog</li>        <li>Hosting 12 months</li>        <li>12 pages w/form and video</li>        <li>One monthly email to your list</li>        <li>1 post a week to Facebook/Instagram pages</li>      </ul>      <button>asdf</button>    </div>  </div>  <div class="grid__item">    Stuff 2
<div class="grid__inner-content"> <ul class="page-marketing__list"> <li>Website template design, 1 of 7 templates without a blog</li> <li>Hosting 12 months</li> <li>12 pages w/form and video</li> <li>One monthly email to your list</li> <li>1 post a week to Facebook/Instagram pages</li> <li>One content update per month to website and security updates</li> <li>$150 a month in Google ad spending</li> <li>Get $100 in free advertising when you enroll</li> <li>1 monthly written blog for your website</li> <li>Ongoing SEO optimizations</li> </ul> <button>asdf</button> </div> </div></div>
<div style="background: green; padding: 2rem;">Stuff</div>

max-height 100% overflowing parent

Firstly you must have a jquery link in you page(Maybe bootstrap add it to your page). Then you need to set an id for div class="row" for example id="row and another id for div class="col-lg-12" for example id="col".

Now:

var realHeight = $('#col').height() - $('#row').height();
$('#my-listgroup').css('height', realHeight + 'px');

<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script><div id="col" style="height:100px;background-color:red;margin:100px;"> <div id="row" style="height:40px;">div row</div> <select id="my-listgroup" size="4" name="ctl02" style="max-height: 100%;">  <option value="item">item</option> <option value="item">item</option> <option value="item">item</option> <option value="item">item</option> <option value="item">item</option> <option value="item">item</option>
</select></div><script> var realHeight = $('#col').height() - $('#row').height(); $('#my-listgroup').css('height', realHeight + 'px');</script>

Why does height: 100% on a child element not apply when the parent element has a min-height/max-height value but no height value?

In the first case, you don't have any height defined so it's clear that the precentage height on child will fail.

From the specification:

Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.

min-height is only a boundary and the height of your element still depend on its content. If you will have one that exceed 300px the element will have more than 300px