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
.container {
background-color: red;
width: 500px;
min-height: 300px;
padding:10px;
}
.child {
background-color: blue;
width: 500px;
height: 400px;
animation:change 2s linear infinite alternate;
}
@keyframes change{
from {
height:100px;
}
}
<div class="container">
<div class="child">
</div>
</div>
Related Topics
Remove Blue Underline from Link
Same Font Except Its Weight Seems Different on Different Browsers
Difference Between "Word-Break: Break-All" Versus "Word-Wrap: Break-Word" in Css
Specificity of Inherited CSS Properties
Css Reset - What Exactly Does It Do
Css :After Not Adding Content to Certain Elements
Difference Between Max-Device-Width and Max-Width For Mobile Web
Pure CSS to Make Font-Size Responsive Based on Dynamic Amount of Characters
Equal Height Rows in CSS Grid Layout
Css Scrollbar Style Cross Browser
Any Way to Declare a Size/Partial Border to a Box
How to Conditionally Apply a Class
Add Bootstrap Glyphicon to Input Box
How to Change Color Property of Mat-Slide-Toggle/ Overwrite CSS of Component