76

I have this problem, I have two divs:

<div style="width:100%; height:50px;" id="div1"></div>
<div style="width:100%;" id="div2"></div>

How do I make div2 occupy remaining height of the page?

thirtydot
  • 224,678
  • 48
  • 389
  • 349

11 Answers11

61

Use absolute positioning:

#div1{
    width: 100%;
    height: 50px;
    background-color:red;/*Development Only*/
}
#div2{
    width: 100%;
    position: absolute;
    top: 50px;
    bottom: 0;
    background-color:blue;/*Development Only*/
}
<div id="div1"></div>
<div id="div2"></div>
ExcellentSP
  • 1,529
  • 4
  • 15
  • 39
Alexander Rafferty
  • 6,134
  • 4
  • 33
  • 55
21

You can use this http://jsfiddle.net/Victornpb/S8g4E/783/

#container {
    display: table;
    width: 400px;
    height: 400px;
}
#container > div{
    display: table-row;
    height: 0;
}
#container > div.fill{
    height: auto;
}

Just apply the class .fill to any of the children to make then occupy the remaining height.

<div id="container">
    <div>
        Lorem ipsum
    </div>
    <div>
        Lorem ipsum
    </div>
    <div class="fill">   <!-- this will fill the remaining height-->
        Lorem ipsum
    </div>
</div>

It works with how many children you want, no additional markup is required.

Vitim.us
  • 20,746
  • 15
  • 92
  • 109
  • 13
    this is great but if you change #container.height: 400px to #container.height = 100% is does not work any more. Is there a way to make to container fill the available height? – Martin Meeser Mar 24 '14 at 08:35
  • 2
    Thanks, this is exactly what I needed. It's a bit ridiculous that the only way to accomplish this with variable heights is by using tables or JavaScript. They get a bad rap, but tables did a lot of things right. – Gavin Dec 10 '14 at 17:29
  • 3
    @Gavin a `div` with `display: table` is not a table. – herman Sep 02 '15 at 18:37
  • 2
    @herman it behaves the same as a table. It's the behavior of tables that got a bad rap, not that it was named "table". – Gavin Sep 03 '15 at 12:39
  • 4
    @Gavin as far as I know it's the fact that a semantic element like `` should not be used for layout purposes. `display: table` provides a way to get similar behaviour without implying the same semantics.
    – herman Sep 03 '15 at 14:00
13

Demo

One way is to set the the div to position:absolute and give it a top of 50px and bottom of 0px;

#div2
{
    position:absolute;
    bottom:0px;
    top:50px
}
Community
  • 1
  • 1
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
  • 11
    What if there are other elements with heights which aren't fixed? – Mark Oct 07 '12 at 00:31
  • 2
    @Mark: good point. This solution doesn't work if the preceding elements have a dynamic or unknown height. In this case I think the only solution would be javascript. Like here for example: http://stackoverflow.com/questions/2023512/how-can-i-make-a-div-take-up-the-rest-of-the-height-of-a-container-div – Jules Colle Nov 27 '12 at 08:22
9

Since you know how many pixels are occupied by the previous content, you can use the calc() function:

height: calc(100% - 50px);
herman
  • 11,740
  • 5
  • 47
  • 58
  • 2
    @kalu Only Opera Mini, IE8 and old stock Android browser (4.3) won't work. Nobody cares about IE8 and Android 4.3 market share is negligible. Opera Mini has more market share, but seems to lack support for a lot of modern things. You could specify a fallback height as a percentage on the line before, which will get overridden in browsers that support calc. – herman Mar 18 '16 at 09:31
8

I faced the same challenge myself and found these 2 answers using flex properties.

CSS

.container {
  display: flex;
  flex-direction: column;
}

.dynamic-element{
  flex: 1;
}
  • 1
    This is really the only solution that doesn't require the TOP position to be fixed, which means the upper portion can vary in height. – Garr Godfrey Sep 16 '21 at 17:57
6

You can use

display: flex;

CSS property, as mentioned before by @Ayan, but I've created a working example: https://jsfiddle.net/d2kjxd51/

Cezary Tomczyk
  • 584
  • 1
  • 7
  • 14
  • Beware of browser support: http://caniuse.com/#search=flex (especially if you want the solution to work on IE) – Gyum Fox Jun 13 '17 at 10:29
5

With CSS tables, you could wrap a div around the two you have there and use this css/html structure:

<style type="text/css">
.container { display:table; width:100%; height:100%;  }
#div1 { display:table-row; height:50px; background-color:red; }
#div2 { display:table-row; background-color:blue; }
</style>

<div class="container">
    <div id="div1"></div>
    <div id="div2"></div>
</div>

Depends on what browsers support these display types, however. I don't think IE8 and below do. EDIT: Scratch that-- IE8 does support CSS tables.

Brendan
  • 4,565
  • 1
  • 24
  • 39
1

I tried with CSS, and or you need to use display: table or you need to use new css that is not yet supported on most browsers (2016).

So, I wrote a jquery plugin to do it for us, I am happy to share it:

 
//Credit Efy Teicher
$(document).ready(function () {
            $(".fillHight").fillHeight();
            $(".fillWidth").fillWidth();
        });

        window.onresize = function (event) {
            $(".fillHight").fillHeight();
            $(".fillWidth").fillWidth();
        }

        $.fn.fillHeight = function () {
            var siblingsHeight = 0;
            this.siblings("div").each(function () {
                siblingsHeight = siblingsHeight + $(this).height();
            });

            var height = this.parent().height() - siblingsHeight;
            this.height(height);
        };

 
        $.fn.fillWidth = function (){
            var siblingsWidth = 0;
            this.siblings("div").each(function () {
                siblingsWidth  += $(this).width();
            });

            var width =this.parent().width() - siblingsWidth;
            this.width(width);
        }
      * {
            box-sizing: border-box;
        }

        html {
        }

        html, body, .fillParent {
            height: 100%;
            margin: 0;
            padding: 0;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="fillParent" style="background-color:antiquewhite">
        <div>
            no1
        </div>
        <div class="fillHight">
            no2 fill
        </div>
        <div class="deb">
            no3
        </div>
    </div>
user1911353
  • 171
  • 2
  • 2
1

You could use calc function to calculate remaining height for 2nd div.

*{
  box-sizing: border-box;
}

#div1{
  height: 50px;
  background: skyblue;
}

#div2{
  height: calc(100vh - 50px);
  background: blue;
}
<div id="div1"></div>
<div id="div2"></div>
Abhishek Tewari
  • 387
  • 3
  • 12
0
<div>
  <div id="header">header</div>
  <div id="content">content</div>
  <div id="footer">footer</div>
</div>

#header {
  height: 200px;
}

#content {
  height: 100%;
  margin-bottom: -200px;
  padding-bottom: 200px;
  margin-top: -200px;
  padding-top: 200px;
}

#footer {
  height: 200px;
}
wmzy
  • 1
0

Why not use padding with negative margins? Something like this:

<div class="parent">
  <div class="child1">
  </div>
  <div class="child2">
  </div>
</div>

And then

.parent {
  padding-top: 1em;
}
.child1 {
  margin-top: -1em;
  height: 1em;
}
.child2 {
  margin-top: 0;
  height: 100%;
}
kalu
  • 2,594
  • 1
  • 21
  • 22