270

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 {
  height: 100%;
  margin: 0;
}

#containment {
  min-height: 100%;
  background: pink;
}

#containment-shadow-left {
  height: 100%;
  background: aqua;
}
<div id="containment">
  <div id="containment-shadow-left">
    Hello World!
  </div>
</div>
Stickers
  • 75,527
  • 23
  • 147
  • 186
lamefun
  • 3,862
  • 4
  • 20
  • 22
  • 58
    Modern day solution: give the container `display:flex` and `flex-direction:column` and give the child `flex:1`. – jackocnr Aug 05 '16 at 21:14
  • 3
    @jackocnr That doesn't work in any IE due to a [bug](https://github.com/philipwalton/flexbugs#flexbug-3), it was fixed in Edge. – Stickers Feb 11 '18 at 19:22
  • @jackocnr not working in chrome or firefox in 2021, but it works in some online code editors – maazakn Dec 09 '21 at 17:59

19 Answers19

250

Add height: 1px to parent container. Works in Chrome, FF, Safari.

Kushagra Gour
  • 4,568
  • 2
  • 22
  • 26
  • 13
    Doing this doesn't resolve the issue, effectively you're overriding the min-height:100% setting which achieves nothing that couldn't be achieved with height:100% which isn't what the OP wants – styler Mar 19 '14 at 13:02
  • `height: 1px` should be on parent and `min-height: 100%` on child. How can one override another? – Kushagra Gour Mar 20 '14 at 18:52
  • please demo this, the parent #containment currently has a min-height of 100px, adding height 1px to this will override the min-height it just wont work, taking the min-height out and using height:1px will also not work – styler Mar 20 '14 at 21:33
  • 19
    @styler adding `height: 1px;` will not override the min-height. Quite the opposite. This is the best solution here... demo: http://jsbin.com/mosaboyo/1/edit – jjenzz May 01 '14 at 09:52
  • 3
    See this for why `height: 1px;` works http://stackoverflow.com/questions/2341821/height100-vs-min-height100 – Ben Alavi Aug 14 '14 at 19:56
  • 43
    @jjenzz The problem with this, which I think styler was trying to get at, is that this does not retain the expansion trait of `min-height`. E.g., if there is enough text it will overflow. See http://jsbin.com/vuyapitizo/1/ – binaryfunt Apr 13 '15 at 23:45
  • This is true @BrianFunt! Unfortunately, this is the exact behaviour I require :S...100% height empty child div but that also grows when the screen shrinks and content overflows..is there a nice way to do that? – SleepyProgrammer Jun 01 '15 at 13:36
  • @SleepyProgrammer ptriek's method seems to be the best, although it's not pretty – binaryfunt Jun 14 '15 at 19:04
  • This works even if I set the height : 0 :) I guess the check is min-height is avoided if height : auto. In all the other cases min-height is applied. – pravin Aug 21 '15 at 18:53
  • I guess that the parent height is calculated only if we add an explicit `height`, but the actual height is the one from the `min-height` – Amir Tugi Sep 24 '16 at 20:13
  • 9
    Quoting Paul's comment below: "But it doesn't allow the container to grow, which defeats the purpose of using min-height." https://stackoverflow.com/questions/8468066/child-inside-parent-with-min-height-100-not-inheriting-height#comment66853175_24481020 – Leo Lei Jul 26 '17 at 05:30
  • 1
    This only works some-times, but can cause other issues elsewhere. –  Nov 12 '18 at 21:52
  • I have no idea how on earth this solution worked for me.. – minigeek Sep 28 '21 at 07:05
  • 1
    Setting up `height: 1px` won't fire parent element's ResizeObserver. – Jay Oct 26 '21 at 07:08
201

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 {
  min-height: 300px;
  background-color: rgba(255,255,0,0.5); //yellow
}

.child {
  min-height: inherit;
  background-color: rgba(0,255,0,0.5); //blue
}

p {
  padding: 20px;
  color: red;
  font-family: sans-serif;
  font-weight: bold;
  text-align: center;
}
<div class="parent">
  <div class="child">
    <p>Yellow + Blue = Green :)</p>
  </div>
</div>

This way the child now acts as height 100% of the min-height.

I hope some people find this useful :)

Kevin Upton
  • 3,336
  • 2
  • 21
  • 24
191

This is a reported webkit (chrome/safari) bug, children of parents with min-height can't inherit the height property: https://bugs.webkit.org/show_bug.cgi?id=26559

Apparently Firefox is affected too (can't test in IE at the moment)

Possible workaround:

  • add position:relative to #containment
  • add position:absolute to #containment-shadow-left

The bug doesn't show when the inner element has absolute positioning.

See http://jsfiddle.net/xrebB/

Edit on April 10, 2014

Since I'm currently working on a project for which I really need parent containers with min-height, and child elements inheriting the height of the container, I did some more research.

First: I'm not so sure anymore whether the current browser behaviour really is a bug. CSS2.1 specs say:

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'.

If I put a min-height on my container, I'm not explicitly specifying its height - so my element should get an auto height. And that's exactly what Webkit - and all other browsers - do.

Second, the workaround I found:

If I set my container element to display:table with height:inherit it acts exactly the same way as if I'd give it a min-height of 100%. And - more importantly - if I set the child element to display:table-cell it will perfectly inherit the height of the container element - whether it's 100% or more.

Full CSS:

html, body {
  height: 100%;
  margin: 0;
}

#container {
  background: green;
  display: table;
  height: inherit;
  width: 100%;
}

#content {
  background: red;
  display: table-cell;
}

The markup:

<div id="container">
  <div id="content">
      <p>content</p>
  </div>
</div>

See http://jsfiddle.net/xrebB/54/.

ptriek
  • 9,040
  • 5
  • 31
  • 29
  • Although this is a good solution, I like most the one from @Kushagra Gour, because that does not affect the layout (I don't want to use table diplays...) – Cito Jul 24 '14 at 19:26
  • 3
    Its a strange reading of the spec to conclude that min-/max-height isn't explicit...and by strange I mean wrong. Reading the whole paragraph, in context, this interpretation is incorrect. To clarify why, "height of the containing block," in context, is semantically different then the height property. If instead, the phrasing was "height *property* of the containing block" then Your interpretation would make sense (and be a bug in the spec). – WraithKenny Sep 17 '15 at 18:17
  • position: absolute; min-height: inherit; min-width: inherit; This worked for me –  Nov 12 '18 at 21:56
  • 3
    Note, as the edit (and the bugs.webkit link) mentions, this isn't really a bug — if a parent was `min-height: 20px`, but a child was `height: 120%`, that would influence the parent's height, which would influence the child's height... When the parents height is unknowable, the children can't use it for sizing. – Tom McKenzie Jun 07 '19 at 04:52
  • What's actually so bad about setting the position of the child as absolute? Sure, its a hack but you don't need a clearfix bc of the containing element and since you specify the height of the absolutely positioned child explicitly it passes on its height to its children quite well. Am I missing smth? – Xen_mar Jul 23 '20 at 14:33
  • 4
    Still got this bug in 2021 https://codepen.io/dshung1997/pen/LYxvXNy – hungdoansy Apr 28 '21 at 12:05
49

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;
}
JW.
  • 50,691
  • 36
  • 115
  • 143
17

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 {
  height: 100%;
  margin: 0;
  padding: 0; /* Don't forget Safari */
}

#containment {
  display: grid;
  min-height: 100%;
  background: pink;
}

#containment-shadow-left {
  background: aqua;
}
Steve
  • 8,066
  • 11
  • 70
  • 112
10

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.

Jeremy Hewett
  • 103
  • 1
  • 4
  • 26
    But it doesn't allow the container to grow, which defeats the purpose of using min-height. – Sal Sep 29 '16 at 20:31
  • I needed a wrapper to fill the parent's min-height and height as well. What worked for me was setting min-height to inherit and height to 100%. – Mr. Duhart Sep 16 '19 at 23:02
7

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 {
  margin: 0;
}

.child {
  min-height: 100vh;
  background: pink;
}
<div class="parent">
  <div class="child"></div>
</div>
Stickers
  • 75,527
  • 23
  • 147
  • 186
6

This usually works for me:

.parent {
  min-height: 100px;
  background-color: green;
  display: flex;
}
.child {
  height: inherit;
  width: 100%;
  background-color: red;
}
<!DOCTYPE html>
<html>
  <body>
    <div class="parent">
      <div class="child">
      </div>
    </div>
  </body>
</html>
TylerH
  • 20,799
  • 66
  • 75
  • 101
zyrup
  • 691
  • 2
  • 10
  • 18
5

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.

Mike Hopkins
  • 1,011
  • 1
  • 11
  • 13
1

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>
Pandaiolo
  • 11,165
  • 5
  • 38
  • 70
  • Thanks for the directive solution. That's what I ended up using but I didn't want window height to be the min; rather I wanted to inherit the min-height of the parent so I changed the code to this: var height = elm.parent()[0].offsetHeight; – Sal Sep 29 '16 at 21:46
1

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

Internet Explorer compatible solution

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:

  • Inherit the computed height of the parent (as opposed to inheriting its height property);
  • Allow the parent's height to exceed its 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.

Explanation

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.

Solution in action

html, body {
  height: 100px;
  margin: 0;
}

#containment {
  display: table;
  height: 100%;
  background: pink;
  width: 100%;
}

#containment-shadow-left {
  display: table-row;
  height: 100%;
  background: aqua;
}

#content {
  padding: 15px;
}

#demo {
  display: none;
  background-color: red;
  height: 200px;
}

#demo-checkbox:checked ~ #demo {
  display: block;
}
<div id="containment">
  <div id="containment-shadow-left">
    <div id="content">
      <input id="demo-checkbox" type="checkbox">
      <label for="demo-checkbox">Click here for overflow demo</label>
      <div id="demo">This is taller than #containment</div>
    </div>
  </div>
</div>
1

Adding this to parent component fixed it for me:

display: flex;
flex-direction: column;
Bar Vilek
  • 11
  • 1
1

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>
Jonas Stensved
  • 14,378
  • 5
  • 51
  • 80
0

Just to keep this subject complete, I found a solution not explored Here using Fixed position.

No Overflow

html, body, .wrapper, .parent, .child {
  position: fixed;
  top: 0; 
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: 100%;
}

.child {
  overflow: auto;
  background: gray;
}

.height-50 {
  height: 50%;
  width: 5em;
  margin: 10px auto;
  background: cyan;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">
      
      <div class="height-50"></div>
      
    </div>
  </div>
</div>

With Overflow

html, body, .wrapper, .parent, .child {
  position: fixed;
  top: 0; 
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: 100%;
}

.child {
  overflow: auto;
  background: gray;
}

.height-150 {
  height: 150%;
  width: 5em;
  margin: 10px auto;
  background: cyan;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">
      
      <div class="height-150"></div>
      
    </div>
  </div>
</div>
Arthur
  • 4,870
  • 3
  • 32
  • 57
0

SOLUTION July 06 2022

.parent{
  display: flex; /* very important rule */
  flex-direction: column; /* very important rule */

  min-height: 100%
}

.child{
  height: 100%;

  flex-grow: 1; /* very important rule, simulate flex: 1; */
}
<div class="parent">
  <div class="child">
  </div>
</div>
Ethan
  • 881
  • 8
  • 14
  • 26
Vadim Vetrov
  • 79
  • 1
  • 4
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the [help center](https://stackoverflow.com/help/how-to-answer). – Ethan Jul 11 '22 at 01:38
  • I just tried this in jsfiddle and it doesn't seem to work! – Sahil Jaidka Sep 08 '22 at 05:31
0

It's been a while but, if someone else is still struggling with this, i found my workaround. I need the the parent to have a minimum height,and the children (which will contain several image/files previews) must occupy the whole parent, so..

I simply defined a minimum height to the children a let the parent with no height defined, so it can grow along with the children content.

CSS

.parent{
    border: 1px solid black;
    border-radius: 5px;
}
.children{
  width: 100%;
  min-height: 100px;
}

HTML:

<div class="parent">
    <div class="children">
        some content inside
    </div>
</div>
0

Add align-self: normal to the child item.

-3

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>
coban
  • 122
  • 1
  • 6
-3

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 {
  position: relative;
  min-height: 100%;
}

.child {
  min-height: 100vh;
}
<div class="parent">
    <div class="child"></div>
  </div>
Skoua
  • 3,373
  • 3
  • 38
  • 51