I found a way to make a div container to occupy at least full height of a page, by setting min-height: 100%;
. However, when I add a nested div and set height: 100%;
, it doesn't stretch to container's height. Is there a way to fix it?
html, body {_x000D_
height: 100%;_x000D_
margin: 0;_x000D_
}_x000D_
_x000D_
#containment {_x000D_
min-height: 100%;_x000D_
background: pink;_x000D_
}_x000D_
_x000D_
#containment-shadow-left {_x000D_
height: 100%;_x000D_
background: aqua;_x000D_
}
_x000D_
<div id="containment">_x000D_
<div id="containment-shadow-left">_x000D_
Hello World!_x000D_
</div>_x000D_
</div>
_x000D_
I don't believe this is a bug with browsers. All behave the same way - that is, once you stop specifying explicit heights, min-height is basically a "last step".
It appears to be exactly how the CSS 2.1 spec suggests: http://www.w3.org/TR/CSS2/visudet.html#the-height-property
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'.
Therefore, as the min-height
parent does not have an explicit height
property set, it defaults to auto.
There are some ways around this possibly by using display: table-cell
, or newer styles such as flexbox, if that is possible for your targeted audience's browsers. You can also subvert this in certain situations by using the top
and bottom
properties on an absolutely positioned inner element, which gives you 100% height without specifying so.
This usually works for me:
_x000D_
_x000D_
.parent {_x000D_
min-height: 100px;_x000D_
background-color: green;_x000D_
display: flex;_x000D_
}_x000D_
.child {_x000D_
height: inherit;_x000D_
width: 100%;_x000D_
background-color: red;_x000D_
}
_x000D_
<!DOCTYPE html>_x000D_
<html>_x000D_
<body>_x000D_
<div class="parent">_x000D_
<div class="child">_x000D_
</div>_x000D_
</div>_x000D_
</body>_x000D_
</html>
_x000D_
_x000D_
_x000D_
The best way to achieve this nowadays is to use display: flex;
. However you might run into an issue when trying to support IE11. According to https://caniuse.com using flexbox :
IE 11 does not vertically align items correctly when min-height is used
The solution is to use display: table;
on the parent and display: table-row;
on the child both with height: 100%;
as a replacement for min-height: 100%;
.
Most of the solutions listed here use display:
table
, table-row
and/or table-cell
, but they don't replicate the same behaviour as min-height: 100%;
, which is:
height
property);min-height
;While using this solution, the behaviour is the same and the property min-height
is not needed which allows to get around the bug.
The reason why it works is because, unlike most elements, elements using display:
table
and table-row
will always be as tall as their content. This makes their height
property behave similarly to min-height
.
html, body {_x000D_
height: 100px;_x000D_
margin: 0;_x000D_
}_x000D_
_x000D_
#containment {_x000D_
display: table;_x000D_
height: 100%;_x000D_
background: pink;_x000D_
width: 100%;_x000D_
}_x000D_
_x000D_
#containment-shadow-left {_x000D_
display: table-row;_x000D_
height: 100%;_x000D_
background: aqua;_x000D_
}_x000D_
_x000D_
#content {_x000D_
padding: 15px;_x000D_
}_x000D_
_x000D_
#demo {_x000D_
display: none;_x000D_
background-color: red;_x000D_
height: 200px;_x000D_
}_x000D_
_x000D_
#demo-checkbox:checked ~ #demo {_x000D_
display: block;_x000D_
}
_x000D_
<div id="containment">_x000D_
<div id="containment-shadow-left">_x000D_
<div id="content">_x000D_
<input id="demo-checkbox" type="checkbox">_x000D_
<label for="demo-checkbox">Click here for overflow demo</label>_x000D_
<div id="demo">This is taller than #containment</div>_x000D_
</div>_x000D_
</div>_x000D_
</div>
_x000D_
Although display: flex;
has been suggested here, consider using display: grid;
now that it's widely supported. By default, the only child of a grid will entirely fill its parent.
html, body {_x000D_
height: 100%;_x000D_
margin: 0;_x000D_
padding: 0; /* Don't forget Safari */_x000D_
}_x000D_
_x000D_
#containment {_x000D_
display: grid;_x000D_
min-height: 100%;_x000D_
background: pink;_x000D_
}_x000D_
_x000D_
#containment-shadow-left {_x000D_
background: aqua;_x000D_
}
_x000D_
For googlers:
This jquery-workaround makes #containment get a height automatically (by, height: auto), then gets the actual height assigned as a pixel value.
<script type="text/javascript">
<!--
$(function () {
// workaround for webkit-bug http://stackoverflow.com/a/8468131/348841
var rz = function () {
$('#containment')
.css('height', 'auto')
.css('height', $('#containment').height() + 'px');
};
$(window).resize(function () {
rz();
});
rz();
})
-->
</script>
In addition to the existing answers, there is also viewport units vh
to use. Simple snippet below. Of course it can be used together with calc()
as well, e.g. min-height: calc(100vh - 200px);
when page header and footer have 200px
height together.
body {_x000D_
margin: 0;_x000D_
}_x000D_
_x000D_
.child {_x000D_
min-height: 100vh;_x000D_
background: pink;_x000D_
}
_x000D_
<div class="parent">_x000D_
<div class="child"></div>_x000D_
</div>
_x000D_
Add height: 1px
to parent container. Works in Chrome, FF, Safari.
Just to keep this subject complete, I found a solution not explored Here using Fixed position.
html, body, .wrapper, .parent, .child {_x000D_
position: fixed;_x000D_
top: 0; _x000D_
bottom: 0;_x000D_
left: 0;_x000D_
right: 0;_x000D_
margin: 0;_x000D_
padding: 0;_x000D_
height: 100%;_x000D_
}_x000D_
_x000D_
.child {_x000D_
overflow: auto;_x000D_
background: gray;_x000D_
}_x000D_
_x000D_
.height-50 {_x000D_
height: 50%;_x000D_
width: 5em;_x000D_
margin: 10px auto;_x000D_
background: cyan;_x000D_
}
_x000D_
<div class="wrapper">_x000D_
<div class="parent">_x000D_
<div class="child">_x000D_
_x000D_
<div class="height-50"></div>_x000D_
_x000D_
</div>_x000D_
</div>_x000D_
</div>
_x000D_
html, body, .wrapper, .parent, .child {_x000D_
position: fixed;_x000D_
top: 0; _x000D_
bottom: 0;_x000D_
left: 0;_x000D_
right: 0;_x000D_
margin: 0;_x000D_
padding: 0;_x000D_
height: 100%;_x000D_
}_x000D_
_x000D_
.child {_x000D_
overflow: auto;_x000D_
background: gray;_x000D_
}_x000D_
_x000D_
.height-150 {_x000D_
height: 150%;_x000D_
width: 5em;_x000D_
margin: 10px auto;_x000D_
background: cyan;_x000D_
}
_x000D_
<div class="wrapper">_x000D_
<div class="parent">_x000D_
<div class="child">_x000D_
_x000D_
<div class="height-150"></div>_x000D_
_x000D_
</div>_x000D_
</div>_x000D_
</div>
_x000D_
Kushagra Gour's solution does work (at least in Chrome and IE) and solves the original problem without having to use display: table;
and display: table-cell;
. See plunker: http://plnkr.co/edit/ULEgY1FDCsk8yiRTfOWU
Setting min-height: 100%; height: 1px;
on the outer div causes its actual height to be at least 100%, as required. It also allows the inner div to correctly inherit the height.
Another JS solution, that is easy and can be used to avoid a non-easy CSS-only or extra markup / hacky solution.
function minHeight(elm, percent) {
var windowHeight = isNaN(window.innerHeight) ?
window.clientHeight : window.innerHeight;
var height = windowHeight * percent / 100;
elm.style.minHeight = height + 'px';
}
W/ jQuery :
function minHeight($elm, percent) {
var windowHeight = $(window).height();
var height = windowHeight * percent / 100;
$elm.css('min-height', height + 'px');
}
Angular directive :
myModule.directive('minHeight', ['$window', function($window) {
return {
restrict: 'A',
link: function(scope, elm, attrs) {
var windowHeight = isNaN($window.innerHeight) ?
$window.clientHeight : $window.innerHeight;
var height = windowHeight * attrs.minHeight / 100;
elm.css('min-height', height + 'px');
}
};
}]);
To be used like this :
<div>
<!-- height auto here -->
<div min-height="100">
<!-- This guy is at least 100% of window height but grows if needed -->
</div>
</div>
This is what works for me with percentage-based height and parent still growing according to children height. Works fine in Firefox, Chrome and Safari.
.parent {_x000D_
position: relative;_x000D_
min-height: 100%;_x000D_
}_x000D_
_x000D_
.child {_x000D_
min-height: 100vh;_x000D_
}
_x000D_
<div class="parent">_x000D_
<div class="child"></div>_x000D_
</div>
_x000D_
after trying for ours! chrome understands that I want the child element to be 100% height when I set the display value to inline block. btw setting float will causing it.
display:inline-block
update
this is not working. the solution is to get the parentnode offsetheight and use it at the and of the page with javascript.
<script>
SomedivElement = document.getElementById('mydiv');
SomedivElement.style.height = String(nvleft.parentNode.offsetHeight) + 'px';
</script>
thought I would share this, as I didnt see this anywhere, and is what I used to fix my solution.
SOLUTION: min-height: inherit;
I had a parent with a specified min height, and I needed a child to also be that height.
.parent {_x000D_
min-height: 300px;_x000D_
background-color: rgba(255,255,0,0.5); //yellow_x000D_
}_x000D_
_x000D_
.child {_x000D_
min-height: inherit;_x000D_
background-color: rgba(0,255,0,0.5); //blue_x000D_
}_x000D_
_x000D_
p {_x000D_
padding: 20px;_x000D_
color: red;_x000D_
font-family: sans-serif;_x000D_
font-weight: bold;_x000D_
text-align: center;_x000D_
}
_x000D_
<div class="parent">_x000D_
<div class="child">_x000D_
<p>Yellow + Blue = Green :)</p>_x000D_
</div>_x000D_
</div>
_x000D_
This way the child now acts as height 100% of the min-height.
I hope some people find this useful :)
This was added in a comment by @jackocnr but I missed it. For modern browsers I think this is the best approach.
It makes the inner element fill the whole container if it's too small, but expands the container's height if it's too big.
#containment {
min-height: 100%;
display: flex;
flex-direction: column;
}
#containment-shadow-left {
flex: 1;
}
Source: Stackoverflow.com