Child inside parent with min-height: 100% not inheriting height

CssHtml

Css Problem Overview


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>

Css Solutions


Solution 1 - Css

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

Solution 2 - Css

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

Solution 3 - Css

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 :)

Solution 4 - Css

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;
}

Solution 5 - Css

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.

Solution 6 - Css

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;
}

Solution 7 - Css

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>

Solution 8 - Css

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.

Solution 9 - Css

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>

Solution 10 - Css

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>

Solution 11 - Css

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>

Solution 12 - Css

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>

Solution 13 - Css

Adding this to parent component fixed it for me:

display: flex;
flex-direction: column;

Solution 14 - Css

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>

Solution 15 - Css

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>

Solution 16 - Css

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>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlamefunView Question on Stackoverflow
Solution 1 - CssKushagra GourView Answer on Stackoverflow
Solution 2 - CssptriekView Answer on Stackoverflow
Solution 3 - CssKevin UptonView Answer on Stackoverflow
Solution 4 - CssJW.View Answer on Stackoverflow
Solution 5 - CssJeremy HewettView Answer on Stackoverflow
Solution 6 - CssSteveView Answer on Stackoverflow
Solution 7 - CssStickersView Answer on Stackoverflow
Solution 8 - CssMike HopkinsView Answer on Stackoverflow
Solution 9 - CsszyrupView Answer on Stackoverflow
Solution 10 - CssJonas StensvedView Answer on Stackoverflow
Solution 11 - CssPandaioloView Answer on Stackoverflow
Solution 12 - CssSimon MartineauView Answer on Stackoverflow
Solution 13 - CssBar VilekView Answer on Stackoverflow
Solution 14 - CssArthurView Answer on Stackoverflow
Solution 15 - CsscobanView Answer on Stackoverflow
Solution 16 - CssSkouaView Answer on Stackoverflow