[html] Make a div fill the height of the remaining screen space

I am working on a web application where I want the content to fill the height of the entire screen.

The page has a header, which contains a logo, and account information. This could be an arbitrary height. I want the content div to fill the rest of the page to the bottom.

I have a header div and a content div. At the moment I am using a table for the layout like so:

CSS and HTML

_x000D_
_x000D_
#page {_x000D_
    height: 100%; width: 100%_x000D_
}_x000D_
_x000D_
#tdcontent {_x000D_
    height: 100%;_x000D_
}_x000D_
_x000D_
#content {_x000D_
    overflow: auto; /* or overflow: hidden; */_x000D_
}
_x000D_
<table id="page">_x000D_
    <tr>_x000D_
        <td id="tdheader">_x000D_
            <div id="header">...</div>_x000D_
        </td>_x000D_
    </tr>_x000D_
    <tr>_x000D_
        <td id="tdcontent">_x000D_
            <div id="content">...</div>_x000D_
        </td>_x000D_
    </tr>_x000D_
</table>
_x000D_
_x000D_
_x000D_

The entire height of the page is filled, and no scrolling is required.

For anything inside the content div, setting top: 0; will put it right underneath the header. Sometimes the content will be a real table, with its height set to 100%. Putting header inside content will not allow this to work.

Is there a way to achieve the same effect without using the table?

Update:

Elements inside the content div will have heights set to percentages as well. So something at 100% inside the div will fill it to the bottom. As will two elements at 50%.

Update 2:

For instance, if the header takes up 20% of the screen's height, a table specified at 50% inside #content would take up 40% of the screen space. So far, wrapping the entire thing in a table is the only thing that works.

This question is related to html css html-table

The answer is


I've been searching for an answer for this as well. If you are fortunate enough to be able to target IE8 and up, you can use display:table and related values to get the rendering rules of tables with block-level elements including div.

If you are even luckier and your users are using top-tier browsers (for example, if this is an intranet app on computers you control, like my latest project is), you can use the new Flexible Box Layout in CSS3!


For mobile app i use only VH and VW

<div class="container">
  <div class="title">Title</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>

.container {
  width: 100vw;
  height: 100vh;
  font-size: 5vh;
}

.title {
  height: 20vh;
  background-color: red;
}

.content {
  height: 60vh;
  background: blue;
}

.footer {
  height: 20vh;
  background: green;
}

Demo - https://jsfiddle.net/u763ck92/


It's dynamic calc the remining screen space, better using Javascript.

You can use CSS-IN-JS technology, like below lib:

https://github.com/cssobj/cssobj

DEMO: https://cssobj.github.io/cssobj-demo/


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
    height: 100%;
    margin: 0;
    padding: 0;
    color: #FFF;
}

#header
{
    float: left;
    width: 100%;
    background: red;
}

#content
{
    height: 100%;
    overflow: auto;
    background: blue;
}

</style>
</head>
<body>

    <div id="content">
        <div id="header">
                Header
                <p>Header stuff</p>
        </div>
            Content
            <p>Content stuff</p>
    </div>

</body>
</html>

In all sane browsers, you can put the "header" div before the content, as a sibling, and the same CSS will work. However, IE7- does not interpret the height correctly if the float is 100% in that case, so the header needs to be IN the content, as above. The overflow: auto will cause double scroll bars on IE (which always has the viewport scrollbar visible, but disabled), but without it, the content will clip if it overflows.


CSS Grid Solution

Just defining the body with display:grid and the grid-template-rows using auto and the fr value property.

_x000D_
_x000D_
* {_x000D_
  margin: 0;_x000D_
  padding: 0;_x000D_
}_x000D_
_x000D_
html {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
body {_x000D_
  min-height: 100%;_x000D_
  display: grid;_x000D_
  grid-template-rows: auto 1fr auto;_x000D_
}_x000D_
_x000D_
header {_x000D_
  padding: 1em;_x000D_
  background: pink;_x000D_
}_x000D_
_x000D_
main {_x000D_
  padding: 1em;_x000D_
  background: lightblue;_x000D_
}_x000D_
_x000D_
footer {_x000D_
  padding: 2em;_x000D_
  background: lightgreen;_x000D_
}_x000D_
_x000D_
main:hover {_x000D_
  height: 2000px;_x000D_
  /* demos expansion of center element */_x000D_
}
_x000D_
<header>HEADER</header>_x000D_
<main>MAIN</main>_x000D_
<footer>FOOTER</footer>
_x000D_
_x000D_
_x000D_

A Complete Guide to Grids @ CSS-Tricks.com


One more solution using CSS Grid

Define grid

.root {
  display: grid;
  grid-template-rows: minmax(60px, auto) minmax(0, 100%);
}

First row(header): Min height can be set-up and max height will depend on content. Second row(content) will try to fit free space that left after header.

The advantage of this approach is content can be scrolled independently of header, so header is always at the top of the page

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

.root {
  display: grid;
  grid-template-rows: minmax(60px, auto) minmax(0, 100%);
  height: 100%;
}

.header {
  background-color: lightblue;
}

button {
  background-color: darkslateblue;
  color: white;
  padding: 10px 50px;
  margin: 10px 30px;
  border-radius: 15px;
  border: none;
}

.content {
  background-color: antiquewhite;
  overflow: auto;
}

.block {
  width: calc(100% - 20px);
  height: 120px;
  border: solid aquamarine;
  margin: 10px;
}
_x000D_
<div class="root">
  <div class="header">
    <button>click</button>
    <button>click</button>
    <button>click</button>
    <button>click</button>
    <button>click</button>
  </div>
  <div class="content">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
</div>
  <div class="footer"></div>
</div>
_x000D_
_x000D_
_x000D_


 style="height:100vh"

solved the problem for me. In my case I applied this to the required div


How about you simply use vh which stands for view height in CSS...

Look at the code snippet I created for you below and run it:

_x000D_
_x000D_
body {_x000D_
  padding: 0;_x000D_
  margin: 0;_x000D_
}_x000D_
_x000D_
.full-height {_x000D_
  width: 100px;_x000D_
  height: 100vh;_x000D_
  background: red;_x000D_
}
_x000D_
<div class="full-height">_x000D_
</div>
_x000D_
_x000D_
_x000D_

Also, look at the image below which I created for you:

Make a div fill the height of the remaining screen space


What worked for me (with a div within another div and I assume in all other circumstances) is to set the bottom padding to 100%. That is, add this to your css / stylesheet:

padding-bottom: 100%;

There really isn't a sound, cross-browser way to do this in CSS. Assuming your layout has complexities, you need to use JavaScript to set the element's height. The essence of what you need to do is:

Element Height = Viewport height - element.offset.top - desired bottom margin

Once you can get this value and set the element's height, you need to attach event handlers to both the window onload and onresize so that you can fire your resize function.

Also, assuming your content could be larger than the viewport, you will need to set overflow-y to scroll.


Spinning off the idea of Mr. Alien...

This seems a cleaner solution than the popular flex box one for CSS3 enabled browsers.

Simply use min-height(instead of height) with calc() to the content block.

The calc() starts with 100% and subtracts heights of headers and footers (need to include padding values)

Using "min-height" instead of "height" is particularly useful so it can work with javascript rendered content and JS frameworks like Angular2. Otherwise, the calculation will not push the footer to the bottom of the page once the javascript rendered content is visible.

Here is a simple example of a header and footer using 50px height and 20px padding for both.

Html:

<body>
    <header></header>
    <div class="content"></div>
    <footer></footer>
</body>

Css:

.content {
    min-height: calc(100% - (50px + 20px + 20px + 50px + 20px + 20px));
}

Of course, the math can be simplified but you get the idea...


I wresteled with this for a while and ended up with the following:

Since it is easy to make the content DIV the same height as the parent but apparently difficult to make it the parent height minus the header height I decided to make content div full height but position it absolutely in the top left corner and then define a padding for the top which has the height of the header. This way the content displays neatly under the header and fills the whole remaining space:

body {
    padding: 0;
    margin: 0;
    height: 100%;
    overflow: hidden;
}

#header {
    position: absolute;
    top: 0;
    left: 0;
    height: 50px;
}

#content {
    position: absolute;
    top: 0;
    left: 0;
    padding-top: 50px;
    height: 100%;
}

 style="height:100vh"

solved the problem for me. In my case I applied this to the required div


Instead of using tables in the markup, you could use CSS tables.

Markup

<body>    
    <div>hello </div>
    <div>there</div>
</body>

(Relevant) CSS

body
{
    display:table;
    width:100%;
}
div
{
    display:table-row;
}
div+ div
{
    height:100%;  
}

FIDDLE1 and FIDDLE2

Some advantages of this method are:

1) Less markup

2) Markup is more semantic than tables, because this is not tabular data.

3) Browser support is very good: IE8+, All modern browsers and mobile devices (caniuse)


Just for completeness, here are the equivalent Html elements to css properties for the The CSS table model

table    { display: table }
tr       { display: table-row }
thead    { display: table-header-group }
tbody    { display: table-row-group }
tfoot    { display: table-footer-group }
col      { display: table-column }
colgroup { display: table-column-group }
td, th   { display: table-cell }
caption  { display: table-caption } 

The original post is more than 3 years ago. I guess many people who come to this post like me are looking for an app-like layout solution, say a somehow fixed header, footer, and full height content taking up the rest screen. If so, this post may help, it works on IE7+, etc.

http://blog.stevensanderson.com/2011/10/05/full-height-app-layouts-a-css-trick-to-make-it-easier/

And here are some snippets from that post:

_x000D_
_x000D_
@media screen { _x000D_
  _x000D_
  /* start of screen rules. */ _x000D_
  _x000D_
  /* Generic pane rules */_x000D_
  body { margin: 0 }_x000D_
  .row, .col { overflow: hidden; position: absolute; }_x000D_
  .row { left: 0; right: 0; }_x000D_
  .col { top: 0; bottom: 0; }_x000D_
  .scroll-x { overflow-x: auto; }_x000D_
  .scroll-y { overflow-y: auto; }_x000D_
_x000D_
  .header.row { height: 75px; top: 0; }_x000D_
  .body.row { top: 75px; bottom: 50px; }_x000D_
  .footer.row { height: 50px; bottom: 0; }_x000D_
  _x000D_
  /* end of screen rules. */ _x000D_
}
_x000D_
<div class="header row" style="background:yellow;">_x000D_
    <h2>My header</h2>_x000D_
</div> _x000D_
<div class="body row scroll-y" style="background:lightblue;">_x000D_
    <p>The body</p>_x000D_
</div> _x000D_
<div class="footer row" style="background:#e9e9e9;">_x000D_
    My footer_x000D_
</div>
_x000D_
_x000D_
_x000D_


There really isn't a sound, cross-browser way to do this in CSS. Assuming your layout has complexities, you need to use JavaScript to set the element's height. The essence of what you need to do is:

Element Height = Viewport height - element.offset.top - desired bottom margin

Once you can get this value and set the element's height, you need to attach event handlers to both the window onload and onresize so that you can fire your resize function.

Also, assuming your content could be larger than the viewport, you will need to set overflow-y to scroll.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
    height: 100%;
    margin: 0;
    padding: 0;
    color: #FFF;
}

#header
{
    float: left;
    width: 100%;
    background: red;
}

#content
{
    height: 100%;
    overflow: auto;
    background: blue;
}

</style>
</head>
<body>

    <div id="content">
        <div id="header">
                Header
                <p>Header stuff</p>
        </div>
            Content
            <p>Content stuff</p>
    </div>

</body>
</html>

In all sane browsers, you can put the "header" div before the content, as a sibling, and the same CSS will work. However, IE7- does not interpret the height correctly if the float is 100% in that case, so the header needs to be IN the content, as above. The overflow: auto will cause double scroll bars on IE (which always has the viewport scrollbar visible, but disabled), but without it, the content will clip if it overflows.


Disclaimer: The accepted answer gives the idea of the solution, but I'm finding it a bit bloated with an unnecessary wrapper and css rules. Below is a solution with very few css rules.

HTML 5

<body>
    <header>Header with an arbitrary height</header>
    <main>
        This container will grow so as to take the remaining height
    </main>
</body>

CSS

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;       /* body takes whole viewport's height */
}

main {
  flex: 1;                 /* this will make the container take the free space */
}

Solution above uses viewport units and flexbox, and is therefore IE10+, providing you use the old syntax for IE10.

Codepen to play with: link to codepen

Or this one, for those needing the main container to be scrollable in case of overflowing content: link to codepen


CSS only Approach (If height is known/fixed)

When you want the middle element to span across entire page vertically, you can use calc() which is introduced in CSS3.

Assuming we have a fixed height header and footer elements and we want the section tag to take entire available vertical height...

Demo

Assumed markup and your CSS should be

_x000D_
_x000D_
html,_x000D_
body {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
header {_x000D_
  height: 100px;_x000D_
  background: grey;_x000D_
}_x000D_
_x000D_
section {_x000D_
  height: calc(100% - (100px + 150px));_x000D_
  /* Adding 100px of header and 150px of footer */_x000D_
  background: tomato;_x000D_
}_x000D_
_x000D_
footer {_x000D_
  height: 150px;_x000D_
  background-color: blue;_x000D_
}
_x000D_
<header>100px</header>_x000D_
<section>Expand me for remaining space</section>_x000D_
<footer>150px</footer>
_x000D_
_x000D_
_x000D_

So here, what am doing is, adding up the height of elements and than deducting from 100% using calc() function.

Just make sure that you use height: 100%; for the parent elements.


Vincent, I'll answer again using your new requirements. Since you don't care about the content being hidden if it's too long, you don't need to float the header. Just put overflow hidden on the html and body tags, and set #content height to 100%. The content will always be longer than the viewport by the height of the header, but it'll be hidden and won't cause scrollbars.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
    <style type="text/css">
    body, html {
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
      color: #FFF;
    }
    p {
      margin: 0;
    }

    #header {
      background: red;
    }

    #content {
      position: relative;
      height: 100%;
      background: blue;
    }

    #content #positioned {
      position: absolute;
      top: 0;
      right: 0;
    }
  </style>
</head>

<body>
  <div id="header">
    Header
    <p>Header stuff</p>
  </div>

  <div id="content">
    Content
    <p>Content stuff</p>
    <div id="positioned">Positioned Content</div>
  </div>

</body>
</html>

For mobile app i use only VH and VW

<div class="container">
  <div class="title">Title</div>
  <div class="content">Content</div>
  <div class="footer">Footer</div>
</div>

.container {
  width: 100vw;
  height: 100vh;
  font-size: 5vh;
}

.title {
  height: 20vh;
  background-color: red;
}

.content {
  height: 60vh;
  background: blue;
}

.footer {
  height: 20vh;
  background: green;
}

Demo - https://jsfiddle.net/u763ck92/


it never worked for me in other way then with use of the JavaScript as NICCAI suggested in the very first answer. I am using that approach to rescale the <div> with the Google Maps.

Here is the full example how to do that (works in Safari/FireFox/IE/iPhone/Andorid (works with rotation)):

CSS

body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.header {
  height: 100px;
  background-color: red;
}

.content {
  height: 100%;
  background-color: green;
}

JS

function resize() {
  // Get elements and necessary element heights
  var contentDiv = document.getElementById("contentId");
  var headerDiv = document.getElementById("headerId");
  var headerHeight = headerDiv.offsetHeight;

  // Get view height
  var viewportHeight = document.getElementsByTagName('body')[0].clientHeight;

  // Compute the content height - we want to fill the whole remaining area
  // in browser window
  contentDiv.style.height = viewportHeight - headerHeight;
}

window.onload = resize;
window.onresize = resize;

HTML

<body>
  <div class="header" id="headerId">Hello</div>
  <div class="content" id="contentId"></div>
</body>

None of the solutions posted work when you need the bottom div to scroll when the content is too tall. Here's a solution that works in that case:

_x000D_
_x000D_
.table {_x000D_
  display: table;_x000D_
}_x000D_
_x000D_
.table-row {_x000D_
  display: table-row;_x000D_
}_x000D_
_x000D_
.table-cell {_x000D_
  display: table-cell;_x000D_
}_x000D_
_x000D_
.container {_x000D_
  width: 400px;_x000D_
  height: 300px;_x000D_
}_x000D_
_x000D_
.header {_x000D_
  background: cyan;_x000D_
}_x000D_
_x000D_
.body {_x000D_
  background: yellow;_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
.body-content-outer-wrapper {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
.body-content-inner-wrapper {_x000D_
  height: 100%;_x000D_
  position: relative;_x000D_
  overflow: auto;_x000D_
}_x000D_
_x000D_
.body-content {_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  bottom: 0;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
}
_x000D_
<div class="table container">_x000D_
  <div class="table-row header">_x000D_
    <div>This is the header whose height is unknown</div>_x000D_
    <div>This is the header whose height is unknown</div>_x000D_
    <div>This is the header whose height is unknown</div>_x000D_
  </div>_x000D_
  <div class="table-row body">_x000D_
    <div class="table-cell body-content-outer-wrapper">_x000D_
      <div class="body-content-inner-wrapper">_x000D_
        <div class="body-content">_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
        </div>_x000D_
      </div>_x000D_
    </div>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Original source: Filling the Remaining Height of a Container While Handling Overflow in CSS

JSFiddle live preview


Vincent, I'll answer again using your new requirements. Since you don't care about the content being hidden if it's too long, you don't need to float the header. Just put overflow hidden on the html and body tags, and set #content height to 100%. The content will always be longer than the viewport by the height of the header, but it'll be hidden and won't cause scrollbars.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
    <style type="text/css">
    body, html {
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
      color: #FFF;
    }
    p {
      margin: 0;
    }

    #header {
      background: red;
    }

    #content {
      position: relative;
      height: 100%;
      background: blue;
    }

    #content #positioned {
      position: absolute;
      top: 0;
      right: 0;
    }
  </style>
</head>

<body>
  <div id="header">
    Header
    <p>Header stuff</p>
  </div>

  <div id="content">
    Content
    <p>Content stuff</p>
    <div id="positioned">Positioned Content</div>
  </div>

</body>
</html>

Why not just like this?

html, body {
    height: 100%;
}

#containerInput {
    background-image: url('../img/edit_bg.jpg');
    height: 40%;
}

#containerControl {
    background-image: url('../img/control_bg.jpg');
    height: 60%;
}

Giving you html and body (in that order) a height and then just give your elements a height?

Works for me


If the only issue is height, just using divs seems to work:

<div id="header">header content</div>
<div id="content" style="height:100%">content content</div>

In a simple test, the width of header/content is different in your example and mine, but I'm not sure from your post if you're concerned about the width?


If you can deal with not supporting old browsers (that is, MSIE 9 or older), you can do this with Flexible Box Layout Module which is already W3C CR. That module allows other nice tricks, too, such as re-ordering content.

Unfortunately, MSIE 9 or lesser do not support this and you have to use vendor prefix for the CSS property for every browser other than Firefox. Hopefully other vendors drop the prefix soon, too.

An another choice would be CSS Grid Layout but that has even less support from stable versions of browsers. In practice, only MSIE 10 supports this.

Update year 2020: All modern browsers support both display: flex and display: grid. The only one missing is support for subgrid which in only supported by Firefox. Note that MSIE does not support either by the spec but if you're willing to add MSIE specific CSS hacks, it can be made to behave. I would suggest simply ignoring MSIE because even Microsoft says it should not be used anymore.


Why not just like this?

html, body {
    height: 100%;
}

#containerInput {
    background-image: url('../img/edit_bg.jpg');
    height: 40%;
}

#containerControl {
    background-image: url('../img/control_bg.jpg');
    height: 60%;
}

Giving you html and body (in that order) a height and then just give your elements a height?

Works for me


If the only issue is height, just using divs seems to work:

<div id="header">header content</div>
<div id="content" style="height:100%">content content</div>

In a simple test, the width of header/content is different in your example and mine, but I'm not sure from your post if you're concerned about the width?


This is my own minimal version of Pebbl's solution. Took forever to find the trick to get it to work in IE11. (Also tested in Chrome, Firefox, Edge, and Safari.)

_x000D_
_x000D_
html {
  height: 100%;
}

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

section {
  display: flex;
  flex-direction: column;
  height: 100%;
}

div:first-child {
  background: gold;
}

div:last-child {
  background: plum;
  flex-grow: 1;
}
_x000D_
<body>
  <section>
    <div>FIT</div>
    <div>GROW</div>
  </section>
</body>
_x000D_
_x000D_
_x000D_


Try this

var sizeFooter = function(){
    $(".webfooter")
        .css("padding-bottom", "0px")
        .css("padding-bottom", $(window).height() - $("body").height())
}
$(window).resize(sizeFooter);

How about you simply use vh which stands for view height in CSS...

Look at the code snippet I created for you below and run it:

_x000D_
_x000D_
body {_x000D_
  padding: 0;_x000D_
  margin: 0;_x000D_
}_x000D_
_x000D_
.full-height {_x000D_
  width: 100px;_x000D_
  height: 100vh;_x000D_
  background: red;_x000D_
}
_x000D_
<div class="full-height">_x000D_
</div>
_x000D_
_x000D_
_x000D_

Also, look at the image below which I created for you:

Make a div fill the height of the remaining screen space


If the only issue is height, just using divs seems to work:

<div id="header">header content</div>
<div id="content" style="height:100%">content content</div>

In a simple test, the width of header/content is different in your example and mine, but I'm not sure from your post if you're concerned about the width?


This is my own minimal version of Pebbl's solution. Took forever to find the trick to get it to work in IE11. (Also tested in Chrome, Firefox, Edge, and Safari.)

_x000D_
_x000D_
html {
  height: 100%;
}

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

section {
  display: flex;
  flex-direction: column;
  height: 100%;
}

div:first-child {
  background: gold;
}

div:last-child {
  background: plum;
  flex-grow: 1;
}
_x000D_
<body>
  <section>
    <div>FIT</div>
    <div>GROW</div>
  </section>
</body>
_x000D_
_x000D_
_x000D_


I had the same problem but I could not make work the solution with flexboxes above. So I created my own template, that includes:

  • a header with a fixed size element
  • a footer
  • a side bar with a scrollbar that occupies the remaining height
  • content

I used flexboxes but in a more simple way, using only properties display: flex and flex-direction: row|column:

I do use angular and I want my component sizes to be 100% of their parent element.

The key is to set the size (in percents) for all parents inorder to limit their size. In the following example myapp height has 100% of the viewport.

The main component has 90% of the viewport, because header and footer have 5%.

I posted my template here: https://jsfiddle.net/abreneliere/mrjh6y2e/3

       body{
        margin: 0;
        color: white;
        height: 100%;
    }
    div#myapp
    {
        display: flex;
        flex-direction: column;
        background-color: red; /* <-- painful color for your eyes ! */
        height: 100%; /* <-- if you remove this line, myapp has no limited height */
    }
    div#main /* parent div for sidebar and content */
    {
        display: flex;
        width: 100%;
        height: 90%; 
    }
    div#header {
        background-color: #333;
        height: 5%;
    }
    div#footer {
        background-color: #222;
        height: 5%;
    }
    div#sidebar {
        background-color: #666;
        width: 20%;
        overflow-y: auto;
     }
    div#content {
        background-color: #888;
        width: 80%;
        overflow-y: auto;
    }
    div.fized_size_element {
        background-color: #AAA;
        display: block;
        width: 100px;
        height: 50px;
        margin: 5px;
    }

Html:

<body>
<div id="myapp">
    <div id="header">
        HEADER
        <div class="fized_size_element"></div>

    </div>
    <div id="main">
        <div id="sidebar">
            SIDEBAR
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
        </div>
        <div id="content">
            CONTENT
        </div>
    </div>
    <div id="footer">
        FOOTER
    </div>
</div>
</body>

The original post is more than 3 years ago. I guess many people who come to this post like me are looking for an app-like layout solution, say a somehow fixed header, footer, and full height content taking up the rest screen. If so, this post may help, it works on IE7+, etc.

http://blog.stevensanderson.com/2011/10/05/full-height-app-layouts-a-css-trick-to-make-it-easier/

And here are some snippets from that post:

_x000D_
_x000D_
@media screen { _x000D_
  _x000D_
  /* start of screen rules. */ _x000D_
  _x000D_
  /* Generic pane rules */_x000D_
  body { margin: 0 }_x000D_
  .row, .col { overflow: hidden; position: absolute; }_x000D_
  .row { left: 0; right: 0; }_x000D_
  .col { top: 0; bottom: 0; }_x000D_
  .scroll-x { overflow-x: auto; }_x000D_
  .scroll-y { overflow-y: auto; }_x000D_
_x000D_
  .header.row { height: 75px; top: 0; }_x000D_
  .body.row { top: 75px; bottom: 50px; }_x000D_
  .footer.row { height: 50px; bottom: 0; }_x000D_
  _x000D_
  /* end of screen rules. */ _x000D_
}
_x000D_
<div class="header row" style="background:yellow;">_x000D_
    <h2>My header</h2>_x000D_
</div> _x000D_
<div class="body row scroll-y" style="background:lightblue;">_x000D_
    <p>The body</p>_x000D_
</div> _x000D_
<div class="footer row" style="background:#e9e9e9;">_x000D_
    My footer_x000D_
</div>
_x000D_
_x000D_
_x000D_


It's dynamic calc the remining screen space, better using Javascript.

You can use CSS-IN-JS technology, like below lib:

https://github.com/cssobj/cssobj

DEMO: https://cssobj.github.io/cssobj-demo/


In Bootstrap:

CSS Styles:

html, body {
    height: 100%;
}

1) Just fill the height of the remaining screen space:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1>

    <header>Header</header>
    <div>Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

![enter image description here


2) fill the height of the remaining screen space and aligning content to the middle of the parent element:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1">

    <header>Header</header>
    <div class="d-flex flex-column flex-grow-1 justify-content-center">Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

![enter image description here


CSS only Approach (If height is known/fixed)

When you want the middle element to span across entire page vertically, you can use calc() which is introduced in CSS3.

Assuming we have a fixed height header and footer elements and we want the section tag to take entire available vertical height...

Demo

Assumed markup and your CSS should be

_x000D_
_x000D_
html,_x000D_
body {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
header {_x000D_
  height: 100px;_x000D_
  background: grey;_x000D_
}_x000D_
_x000D_
section {_x000D_
  height: calc(100% - (100px + 150px));_x000D_
  /* Adding 100px of header and 150px of footer */_x000D_
  background: tomato;_x000D_
}_x000D_
_x000D_
footer {_x000D_
  height: 150px;_x000D_
  background-color: blue;_x000D_
}
_x000D_
<header>100px</header>_x000D_
<section>Expand me for remaining space</section>_x000D_
<footer>150px</footer>
_x000D_
_x000D_
_x000D_

So here, what am doing is, adding up the height of elements and than deducting from 100% using calc() function.

Just make sure that you use height: 100%; for the parent elements.


It could be done purely by CSS using vh:

#page {
    display:block; 
    width:100%; 
    height:95vh !important; 
    overflow:hidden;
}

#tdcontent {
    float:left; 
    width:100%; 
    display:block;
}

#content {      
    float:left; 
    width:100%; 
    height:100%; 
    display:block; 
    overflow:scroll;
}

and the HTML

<div id="page">

   <div id="tdcontent"></div>
   <div id="content"></div>

</div>

I checked it, It works in all major browsers: Chrome, IE, and FireFox


I wresteled with this for a while and ended up with the following:

Since it is easy to make the content DIV the same height as the parent but apparently difficult to make it the parent height minus the header height I decided to make content div full height but position it absolutely in the top left corner and then define a padding for the top which has the height of the header. This way the content displays neatly under the header and fills the whole remaining space:

body {
    padding: 0;
    margin: 0;
    height: 100%;
    overflow: hidden;
}

#header {
    position: absolute;
    top: 0;
    left: 0;
    height: 50px;
}

#content {
    position: absolute;
    top: 0;
    left: 0;
    padding-top: 50px;
    height: 100%;
}

If you can deal with not supporting old browsers (that is, MSIE 9 or older), you can do this with Flexible Box Layout Module which is already W3C CR. That module allows other nice tricks, too, such as re-ordering content.

Unfortunately, MSIE 9 or lesser do not support this and you have to use vendor prefix for the CSS property for every browser other than Firefox. Hopefully other vendors drop the prefix soon, too.

An another choice would be CSS Grid Layout but that has even less support from stable versions of browsers. In practice, only MSIE 10 supports this.

Update year 2020: All modern browsers support both display: flex and display: grid. The only one missing is support for subgrid which in only supported by Firefox. Note that MSIE does not support either by the spec but if you're willing to add MSIE specific CSS hacks, it can be made to behave. I would suggest simply ignoring MSIE because even Microsoft says it should not be used anymore.


A simple solution, using flexbox:

_x000D_
_x000D_
html,_x000D_
body {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
body {_x000D_
  display: flex;_x000D_
  flex-direction: column;_x000D_
}_x000D_
_x000D_
.content {_x000D_
  flex-grow: 1;_x000D_
}
_x000D_
<body>_x000D_
  <div>header</div>_x000D_
  <div class="content"></div>_x000D_
</body>
_x000D_
_x000D_
_x000D_

Codepen sample

An alternate solution, with a div centered within the content div


Used: height: calc(100vh - 110px);

code:

_x000D_
_x000D_
  _x000D_
.header { height: 60px; top: 0; background-color: green}_x000D_
.body {_x000D_
    height: calc(100vh - 110px); /*50+60*/_x000D_
    background-color: gray;_x000D_
}_x000D_
.footer { height: 50px; bottom: 0; }_x000D_
  
_x000D_
<div class="header">_x000D_
    <h2>My header</h2>_x000D_
</div> _x000D_
<div class="body">_x000D_
    <p>The body</p>_x000D_
</div> _x000D_
<div class="footer">_x000D_
    My footer_x000D_
</div>
_x000D_
_x000D_
_x000D_


There really isn't a sound, cross-browser way to do this in CSS. Assuming your layout has complexities, you need to use JavaScript to set the element's height. The essence of what you need to do is:

Element Height = Viewport height - element.offset.top - desired bottom margin

Once you can get this value and set the element's height, you need to attach event handlers to both the window onload and onresize so that you can fire your resize function.

Also, assuming your content could be larger than the viewport, you will need to set overflow-y to scroll.


Used: height: calc(100vh - 110px);

code:

_x000D_
_x000D_
  _x000D_
.header { height: 60px; top: 0; background-color: green}_x000D_
.body {_x000D_
    height: calc(100vh - 110px); /*50+60*/_x000D_
    background-color: gray;_x000D_
}_x000D_
.footer { height: 50px; bottom: 0; }_x000D_
  
_x000D_
<div class="header">_x000D_
    <h2>My header</h2>_x000D_
</div> _x000D_
<div class="body">_x000D_
    <p>The body</p>_x000D_
</div> _x000D_
<div class="footer">_x000D_
    My footer_x000D_
</div>
_x000D_
_x000D_
_x000D_


There's a ton of answers now, but I found using height: 100vh; to work on the div element that needs to fill up the entire vertical space available.

In this way, I do not need to play around with display or positioning. This came in handy when using Bootstrap to make a dashboard wherein I had a sidebar and a main. I wanted the main to stretch and fill the entire vertical space so that I could apply a background colour.

div {
    height: 100vh;
}

Supports IE9 and up: click to see the link


Disclaimer: The accepted answer gives the idea of the solution, but I'm finding it a bit bloated with an unnecessary wrapper and css rules. Below is a solution with very few css rules.

HTML 5

<body>
    <header>Header with an arbitrary height</header>
    <main>
        This container will grow so as to take the remaining height
    </main>
</body>

CSS

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;       /* body takes whole viewport's height */
}

main {
  flex: 1;                 /* this will make the container take the free space */
}

Solution above uses viewport units and flexbox, and is therefore IE10+, providing you use the old syntax for IE10.

Codepen to play with: link to codepen

Or this one, for those needing the main container to be scrollable in case of overflowing content: link to codepen


Vincent, I'll answer again using your new requirements. Since you don't care about the content being hidden if it's too long, you don't need to float the header. Just put overflow hidden on the html and body tags, and set #content height to 100%. The content will always be longer than the viewport by the height of the header, but it'll be hidden and won't cause scrollbars.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
    <style type="text/css">
    body, html {
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
      color: #FFF;
    }
    p {
      margin: 0;
    }

    #header {
      background: red;
    }

    #content {
      position: relative;
      height: 100%;
      background: blue;
    }

    #content #positioned {
      position: absolute;
      top: 0;
      right: 0;
    }
  </style>
</head>

<body>
  <div id="header">
    Header
    <p>Header stuff</p>
  </div>

  <div id="content">
    Content
    <p>Content stuff</p>
    <div id="positioned">Positioned Content</div>
  </div>

</body>
</html>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
    height: 100%;
    margin: 0;
    padding: 0;
    color: #FFF;
}

#header
{
    float: left;
    width: 100%;
    background: red;
}

#content
{
    height: 100%;
    overflow: auto;
    background: blue;
}

</style>
</head>
<body>

    <div id="content">
        <div id="header">
                Header
                <p>Header stuff</p>
        </div>
            Content
            <p>Content stuff</p>
    </div>

</body>
</html>

In all sane browsers, you can put the "header" div before the content, as a sibling, and the same CSS will work. However, IE7- does not interpret the height correctly if the float is 100% in that case, so the header needs to be IN the content, as above. The overflow: auto will cause double scroll bars on IE (which always has the viewport scrollbar visible, but disabled), but without it, the content will clip if it overflows.


It could be done purely by CSS using vh:

#page {
    display:block; 
    width:100%; 
    height:95vh !important; 
    overflow:hidden;
}

#tdcontent {
    float:left; 
    width:100%; 
    display:block;
}

#content {      
    float:left; 
    width:100%; 
    height:100%; 
    display:block; 
    overflow:scroll;
}

and the HTML

<div id="page">

   <div id="tdcontent"></div>
   <div id="content"></div>

</div>

I checked it, It works in all major browsers: Chrome, IE, and FireFox


There really isn't a sound, cross-browser way to do this in CSS. Assuming your layout has complexities, you need to use JavaScript to set the element's height. The essence of what you need to do is:

Element Height = Viewport height - element.offset.top - desired bottom margin

Once you can get this value and set the element's height, you need to attach event handlers to both the window onload and onresize so that you can fire your resize function.

Also, assuming your content could be larger than the viewport, you will need to set overflow-y to scroll.


I found a quite simple solution, because for me it was just a design issue. I wanted the rest of the Page not to be white below the red footer. So i set the pages background color to red. And the contents backgroundcolor to white. With the contents height set to eg. 20em or 50% an almost empty page won't leave the whole page red.


Vincent, I'll answer again using your new requirements. Since you don't care about the content being hidden if it's too long, you don't need to float the header. Just put overflow hidden on the html and body tags, and set #content height to 100%. The content will always be longer than the viewport by the height of the header, but it'll be hidden and won't cause scrollbars.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
    <style type="text/css">
    body, html {
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
      color: #FFF;
    }
    p {
      margin: 0;
    }

    #header {
      background: red;
    }

    #content {
      position: relative;
      height: 100%;
      background: blue;
    }

    #content #positioned {
      position: absolute;
      top: 0;
      right: 0;
    }
  </style>
</head>

<body>
  <div id="header">
    Header
    <p>Header stuff</p>
  </div>

  <div id="content">
    Content
    <p>Content stuff</p>
    <div id="positioned">Positioned Content</div>
  </div>

</body>
</html>

Try this

var sizeFooter = function(){
    $(".webfooter")
        .css("padding-bottom", "0px")
        .css("padding-bottom", $(window).height() - $("body").height())
}
$(window).resize(sizeFooter);

You can actually use display: table to split the area into two elements (header and content), where the header can vary in height and the content fills the remaining space. This works with the whole page, as well as when the area is simply the content of another element positioned with position set to relative, absolute or fixed. It will work as long as the parent element has a non-zero height.

See this fiddle and also the code below:

CSS:

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

p {
    margin: 0;
    padding: 0;
}

.additional-padding {
    height: 50px;
    background-color: #DE9;
}

.as-table {
    display: table;
    height: 100%;
    width: 100%;
}

.as-table-row {
    display: table-row;
    height: 100%;
}

#content {
    width: 100%;
    height: 100%;
    background-color: #33DD44;
}

HTML:

<div class="as-table">
    <div id="header">
        <p>This header can vary in height, it also doesn't have to be displayed as table-row. It will simply take the necessary space and the rest below will be taken by the second div which is displayed as table-row. Now adding some copy to artificially expand the header.</p>
        <div class="additional-padding"></div>
    </div>
    <div class="as-table-row">
        <div id="content">
            <p>This is the actual content that takes the rest of the available space.</p>
        </div>
    </div>
</div>

Spinning off the idea of Mr. Alien...

This seems a cleaner solution than the popular flex box one for CSS3 enabled browsers.

Simply use min-height(instead of height) with calc() to the content block.

The calc() starts with 100% and subtracts heights of headers and footers (need to include padding values)

Using "min-height" instead of "height" is particularly useful so it can work with javascript rendered content and JS frameworks like Angular2. Otherwise, the calculation will not push the footer to the bottom of the page once the javascript rendered content is visible.

Here is a simple example of a header and footer using 50px height and 20px padding for both.

Html:

<body>
    <header></header>
    <div class="content"></div>
    <footer></footer>
</body>

Css:

.content {
    min-height: calc(100% - (50px + 20px + 20px + 50px + 20px + 20px));
}

Of course, the math can be simplified but you get the idea...


If the only issue is height, just using divs seems to work:

<div id="header">header content</div>
<div id="content" style="height:100%">content content</div>

In a simple test, the width of header/content is different in your example and mine, but I'm not sure from your post if you're concerned about the width?


In Bootstrap:

CSS Styles:

html, body {
    height: 100%;
}

1) Just fill the height of the remaining screen space:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1>

    <header>Header</header>
    <div>Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

![enter image description here


2) fill the height of the remaining screen space and aligning content to the middle of the parent element:

<body class="d-flex flex-column">
  <div class="d-flex flex-column flex-grow-1">

    <header>Header</header>
    <div class="d-flex flex-column flex-grow-1 justify-content-center">Content</div>
    <footer class="mt-auto">Footer</footer>

  </div>
</body>

![enter image description here


Instead of using tables in the markup, you could use CSS tables.

Markup

<body>    
    <div>hello </div>
    <div>there</div>
</body>

(Relevant) CSS

body
{
    display:table;
    width:100%;
}
div
{
    display:table-row;
}
div+ div
{
    height:100%;  
}

FIDDLE1 and FIDDLE2

Some advantages of this method are:

1) Less markup

2) Markup is more semantic than tables, because this is not tabular data.

3) Browser support is very good: IE8+, All modern browsers and mobile devices (caniuse)


Just for completeness, here are the equivalent Html elements to css properties for the The CSS table model

table    { display: table }
tr       { display: table-row }
thead    { display: table-header-group }
tbody    { display: table-row-group }
tfoot    { display: table-footer-group }
col      { display: table-column }
colgroup { display: table-column-group }
td, th   { display: table-cell }
caption  { display: table-caption } 

One more solution using CSS Grid

Define grid

.root {
  display: grid;
  grid-template-rows: minmax(60px, auto) minmax(0, 100%);
}

First row(header): Min height can be set-up and max height will depend on content. Second row(content) will try to fit free space that left after header.

The advantage of this approach is content can be scrolled independently of header, so header is always at the top of the page

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

.root {
  display: grid;
  grid-template-rows: minmax(60px, auto) minmax(0, 100%);
  height: 100%;
}

.header {
  background-color: lightblue;
}

button {
  background-color: darkslateblue;
  color: white;
  padding: 10px 50px;
  margin: 10px 30px;
  border-radius: 15px;
  border: none;
}

.content {
  background-color: antiquewhite;
  overflow: auto;
}

.block {
  width: calc(100% - 20px);
  height: 120px;
  border: solid aquamarine;
  margin: 10px;
}
_x000D_
<div class="root">
  <div class="header">
    <button>click</button>
    <button>click</button>
    <button>click</button>
    <button>click</button>
    <button>click</button>
  </div>
  <div class="content">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
</div>
  <div class="footer"></div>
</div>
_x000D_
_x000D_
_x000D_


CSS3 Simple Way

height: calc(100% - 10px); // 10px is height of your first div...

all major browsers these days support it, so go ahead if you don't have requirement to support vintage browsers.


I found a quite simple solution, because for me it was just a design issue. I wanted the rest of the Page not to be white below the red footer. So i set the pages background color to red. And the contents backgroundcolor to white. With the contents height set to eg. 20em or 50% an almost empty page won't leave the whole page red.


You can actually use display: table to split the area into two elements (header and content), where the header can vary in height and the content fills the remaining space. This works with the whole page, as well as when the area is simply the content of another element positioned with position set to relative, absolute or fixed. It will work as long as the parent element has a non-zero height.

See this fiddle and also the code below:

CSS:

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

p {
    margin: 0;
    padding: 0;
}

.additional-padding {
    height: 50px;
    background-color: #DE9;
}

.as-table {
    display: table;
    height: 100%;
    width: 100%;
}

.as-table-row {
    display: table-row;
    height: 100%;
}

#content {
    width: 100%;
    height: 100%;
    background-color: #33DD44;
}

HTML:

<div class="as-table">
    <div id="header">
        <p>This header can vary in height, it also doesn't have to be displayed as table-row. It will simply take the necessary space and the rest below will be taken by the second div which is displayed as table-row. Now adding some copy to artificially expand the header.</p>
        <div class="additional-padding"></div>
    </div>
    <div class="as-table-row">
        <div id="content">
            <p>This is the actual content that takes the rest of the available space.</p>
        </div>
    </div>
</div>

it never worked for me in other way then with use of the JavaScript as NICCAI suggested in the very first answer. I am using that approach to rescale the <div> with the Google Maps.

Here is the full example how to do that (works in Safari/FireFox/IE/iPhone/Andorid (works with rotation)):

CSS

body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.header {
  height: 100px;
  background-color: red;
}

.content {
  height: 100%;
  background-color: green;
}

JS

function resize() {
  // Get elements and necessary element heights
  var contentDiv = document.getElementById("contentId");
  var headerDiv = document.getElementById("headerId");
  var headerHeight = headerDiv.offsetHeight;

  // Get view height
  var viewportHeight = document.getElementsByTagName('body')[0].clientHeight;

  // Compute the content height - we want to fill the whole remaining area
  // in browser window
  contentDiv.style.height = viewportHeight - headerHeight;
}

window.onload = resize;
window.onresize = resize;

HTML

<body>
  <div class="header" id="headerId">Hello</div>
  <div class="content" id="contentId"></div>
</body>

I had the same problem but I could not make work the solution with flexboxes above. So I created my own template, that includes:

  • a header with a fixed size element
  • a footer
  • a side bar with a scrollbar that occupies the remaining height
  • content

I used flexboxes but in a more simple way, using only properties display: flex and flex-direction: row|column:

I do use angular and I want my component sizes to be 100% of their parent element.

The key is to set the size (in percents) for all parents inorder to limit their size. In the following example myapp height has 100% of the viewport.

The main component has 90% of the viewport, because header and footer have 5%.

I posted my template here: https://jsfiddle.net/abreneliere/mrjh6y2e/3

       body{
        margin: 0;
        color: white;
        height: 100%;
    }
    div#myapp
    {
        display: flex;
        flex-direction: column;
        background-color: red; /* <-- painful color for your eyes ! */
        height: 100%; /* <-- if you remove this line, myapp has no limited height */
    }
    div#main /* parent div for sidebar and content */
    {
        display: flex;
        width: 100%;
        height: 90%; 
    }
    div#header {
        background-color: #333;
        height: 5%;
    }
    div#footer {
        background-color: #222;
        height: 5%;
    }
    div#sidebar {
        background-color: #666;
        width: 20%;
        overflow-y: auto;
     }
    div#content {
        background-color: #888;
        width: 80%;
        overflow-y: auto;
    }
    div.fized_size_element {
        background-color: #AAA;
        display: block;
        width: 100px;
        height: 50px;
        margin: 5px;
    }

Html:

<body>
<div id="myapp">
    <div id="header">
        HEADER
        <div class="fized_size_element"></div>

    </div>
    <div id="main">
        <div id="sidebar">
            SIDEBAR
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
            <div class="fized_size_element"></div>
        </div>
        <div id="content">
            CONTENT
        </div>
    </div>
    <div id="footer">
        FOOTER
    </div>
</div>
</body>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
body
,html
{
    height: 100%;
    margin: 0;
    padding: 0;
    color: #FFF;
}

#header
{
    float: left;
    width: 100%;
    background: red;
}

#content
{
    height: 100%;
    overflow: auto;
    background: blue;
}

</style>
</head>
<body>

    <div id="content">
        <div id="header">
                Header
                <p>Header stuff</p>
        </div>
            Content
            <p>Content stuff</p>
    </div>

</body>
</html>

In all sane browsers, you can put the "header" div before the content, as a sibling, and the same CSS will work. However, IE7- does not interpret the height correctly if the float is 100% in that case, so the header needs to be IN the content, as above. The overflow: auto will cause double scroll bars on IE (which always has the viewport scrollbar visible, but disabled), but without it, the content will clip if it overflows.


None of the solutions posted work when you need the bottom div to scroll when the content is too tall. Here's a solution that works in that case:

_x000D_
_x000D_
.table {_x000D_
  display: table;_x000D_
}_x000D_
_x000D_
.table-row {_x000D_
  display: table-row;_x000D_
}_x000D_
_x000D_
.table-cell {_x000D_
  display: table-cell;_x000D_
}_x000D_
_x000D_
.container {_x000D_
  width: 400px;_x000D_
  height: 300px;_x000D_
}_x000D_
_x000D_
.header {_x000D_
  background: cyan;_x000D_
}_x000D_
_x000D_
.body {_x000D_
  background: yellow;_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
.body-content-outer-wrapper {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
.body-content-inner-wrapper {_x000D_
  height: 100%;_x000D_
  position: relative;_x000D_
  overflow: auto;_x000D_
}_x000D_
_x000D_
.body-content {_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  bottom: 0;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
}
_x000D_
<div class="table container">_x000D_
  <div class="table-row header">_x000D_
    <div>This is the header whose height is unknown</div>_x000D_
    <div>This is the header whose height is unknown</div>_x000D_
    <div>This is the header whose height is unknown</div>_x000D_
  </div>_x000D_
  <div class="table-row body">_x000D_
    <div class="table-cell body-content-outer-wrapper">_x000D_
      <div class="body-content-inner-wrapper">_x000D_
        <div class="body-content">_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
          <div>This is the scrollable content whose height is unknown</div>_x000D_
        </div>_x000D_
      </div>_x000D_
    </div>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Original source: Filling the Remaining Height of a Container While Handling Overflow in CSS

JSFiddle live preview


There's a ton of answers now, but I found using height: 100vh; to work on the div element that needs to fill up the entire vertical space available.

In this way, I do not need to play around with display or positioning. This came in handy when using Bootstrap to make a dashboard wherein I had a sidebar and a main. I wanted the main to stretch and fill the entire vertical space so that I could apply a background colour.

div {
    height: 100vh;
}

Supports IE9 and up: click to see the link


I've been searching for an answer for this as well. If you are fortunate enough to be able to target IE8 and up, you can use display:table and related values to get the rendering rules of tables with block-level elements including div.

If you are even luckier and your users are using top-tier browsers (for example, if this is an intranet app on computers you control, like my latest project is), you can use the new Flexible Box Layout in CSS3!


CSS3 Simple Way

height: calc(100% - 10px); // 10px is height of your first div...

all major browsers these days support it, so go ahead if you don't have requirement to support vintage browsers.


CSS Grid Solution

Just defining the body with display:grid and the grid-template-rows using auto and the fr value property.

_x000D_
_x000D_
* {_x000D_
  margin: 0;_x000D_
  padding: 0;_x000D_
}_x000D_
_x000D_
html {_x000D_
  height: 100%;_x000D_
}_x000D_
_x000D_
body {_x000D_
  min-height: 100%;_x000D_
  display: grid;_x000D_
  grid-template-rows: auto 1fr auto;_x000D_
}_x000D_
_x000D_
header {_x000D_
  padding: 1em;_x000D_
  background: pink;_x000D_
}_x000D_
_x000D_
main {_x000D_
  padding: 1em;_x000D_
  background: lightblue;_x000D_
}_x000D_
_x000D_
footer {_x000D_
  padding: 2em;_x000D_
  background: lightgreen;_x000D_
}_x000D_
_x000D_
main:hover {_x000D_
  height: 2000px;_x000D_
  /* demos expansion of center element */_x000D_
}
_x000D_
<header>HEADER</header>_x000D_
<main>MAIN</main>_x000D_
<footer>FOOTER</footer>
_x000D_
_x000D_
_x000D_

A Complete Guide to Grids @ CSS-Tricks.com


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to html-table

Table column sizing DataTables: Cannot read property 'length' of undefined TypeError: a bytes-like object is required, not 'str' in python and CSV How to get the <td> in HTML tables to fit content, and let a specific <td> fill in the rest How to stick table header(thead) on top while scrolling down the table rows with fixed header(navbar) in bootstrap 3? Sorting table rows according to table header column using javascript or jquery How to make background of table cell transparent How to auto adjust table td width from the content bootstrap responsive table content wrapping How to print table using Javascript?