By Vincent McNabb


2008-09-18 05:06:17 8 Comments

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

#page {
    height: 100%; width: 100%
}

#tdcontent {
    height: 100%;
}

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

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.

30 comments

@Alireza 2017-06-17 18:19:17

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:

body {
  padding: 0;
  margin: 0;
}

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

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

Make a div fill the height of the remaining screen space

@LarryBud 2018-03-09 01:53:31

That's only good if you want a div to span the full height of the window. Now put a header div above it with an unknown height.

@Alireza 2018-03-09 02:42:17

@LarryBud you are right, this makes the wrapper div, so everything should goes inside this div...

@Zohab Ali 2018-03-23 10:43:44

 style="height:100vh"

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

@dev.meghraj 2015-08-24 12:57:25

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.

@h--n 2011-10-21 15:02:20

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:

@media screen { 
  
  /* start of screen rules. */ 
  
  /* Generic pane rules */
  body { margin: 0 }
  .row, .col { overflow: hidden; position: absolute; }
  .row { left: 0; right: 0; }
  .col { top: 0; bottom: 0; }
  .scroll-x { overflow-x: auto; }
  .scroll-y { overflow-y: auto; }

  .header.row { height: 75px; top: 0; }
  .body.row { top: 75px; bottom: 50px; }
  .footer.row { height: 50px; bottom: 0; }
  
  /* end of screen rules. */ 
}
<div class="header row" style="background:yellow;">
    <h2>My header</h2>
</div> 
<div class="body row scroll-y" style="background:lightblue;">
    <p>The body</p>
</div> 
<div class="footer row" style="background:#e9e9e9;">
    My footer
</div>

@Roman Starkov 2012-03-04 17:16:43

There’s just one problem with this: the header and footer aren’t auto-sized. That is the real difficulty, and that is why a "this is not possible" answer is currently at the top...

@Matías Cánepa 2012-09-11 00:46:21

I needed a 55px header and a div that fills the rest of the document's height. this is the solution!

@Adam Waite 2013-01-07 10:07:03

You are the bomb, I've been trying this for so long and this is the only solution I found. I needed my nav element to be 60px height at the top and the remainder to span 100%, this solved it.

@GSTAR 2014-03-08 00:38:07

This works well except I am having a slight problem - if I put an element with display: table in the body, it seems to overflow the body. So doing height: 100% doesn't produce the correct height.

@slartidan 2015-11-02 12:34:58

.col is not used, is it?

@Diego Perez 2018-10-02 10:52:23

This solution is not fully responsive. If you have a nav with a menu toggler icon in header that pops down a menu the menu content will be hidden overlapped by main content :s

@Chris 2011-04-11 15:48:06

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!

@Pat M 2016-07-01 20:53:17

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

@Paulie_D 2017-07-04 14:27:17

CSS Grid Solution

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

* {
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

body {
  min-height: 100%;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

header {
  padding: 1em;
  background: pink;
}

main {
  padding: 1em;
  background: lightblue;
}

footer {
  padding: 2em;
  background: lightgreen;
}

main:hover {
  height: 2000px;
  /* demos expansion of center element */
}
<header>HEADER</header>
<main>MAIN</main>
<footer>FOOTER</footer>

A Complete Guide to Grids @ CSS-Tricks.com

@grinmax 2017-02-01 15:59:23

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/

@HarshMarshmallow 2017-04-17 17:59:19

This is not the right solution. vh is inconsistent in mobile browsers. See here for more details: stackoverflow.com/questions/37112218/…

@James Yang 2016-10-13 02:28:18

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/

@Pebbl 2014-07-27 08:14:37

2015 update: the flexbox approach

There are two other answers briefly mentioning flexbox; however, that was more than two years ago, and they don't provide any examples. The specification for flexbox has definitely settled now.

Note: Though CSS Flexible Boxes Layout specification is at the Candidate Recommendation stage, not all browsers have implemented it. WebKit implementation must be prefixed with -webkit-; Internet Explorer implements an old version of the spec, prefixed with -ms-; Opera 12.10 implements the latest version of the spec, unprefixed. See the compatibility table on each property for an up-to-date compatibility status.

(taken from https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)

All major browsers and IE11+ support Flexbox. For IE 10 or older, you can use the FlexieJS shim.

To check current support you can also see here: http://caniuse.com/#feat=flexbox

Working example

With flexbox you can easily switch between any of your rows or columns either having fixed dimensions, content-sized dimensions or remaining-space dimensions. In my example I have set the header to snap to its content (as per the OPs question), I've added a footer to show how to add a fixed-height region and then set the content area to fill up the remaining space.

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

.box {
  display: flex;
  flex-flow: column;
  height: 100%;
}

.box .row {
  border: 1px dotted grey;
}

.box .row.header {
  flex: 0 1 auto;
  /* The above is shorthand for:
  flex-grow: 0,
  flex-shrink: 1,
  flex-basis: auto
  */
}

.box .row.content {
  flex: 1 1 auto;
}

.box .row.footer {
  flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->

<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <p>
      <b>content</b>
      (fills remaining space)
    </p>
  </div>
  <div class="row footer">
    <p><b>footer</b> (fixed height)</p>
  </div>
</div>

In the CSS above, the flex property shorthands the flex-grow, flex-shrink, and flex-basis properties to establish the flexibility of the flex items. Mozilla has a good introduction to the flexible boxes model.

@Erdal G. 2015-11-15 09:36:39

Why the flex: 0 1 30px; attribute in box .row as it's override in every div?

@Brian Burns 2016-05-10 18:40:04

Here's the browser support for flexbox - nice to see all that green - caniuse.com/#feat=flexbox

@ses3ion 2016-06-10 10:49:06

Link to Flexie.js is dead. Here the github project github.com/doctyper/flexie

@Pebbl 2016-06-24 08:45:07

@ses3ion I've updated the flexie link, thanks for the pointer!

@przemcio 2016-07-13 21:55:59

Definitely it is a very good approach and it almost work ;) There is a small problem when a content of div.content exceeds an original flex-ed height. In current implementation the "footer" will be push lower and this is not what the developers expects ;) So I made an very easy fix. jsfiddle.net/przemcio/xLhLuzf9/3 I added additioal flex on container and overflow scroll.

@Pebbl 2016-10-01 11:51:57

@przemcio nice point, but I don't think having scrollable content is what every developer expects ;) — you should only need to add overflow-y: auto to .row.content to achieve what you need however.

@Atomosk 2017-03-09 02:33:07

@bburns.km all green is nice. Even with all possible prefixes flex often doesn't work in old mobile browsers like Android < 4.4. Flex is great, but only if you are lucky enough to not support all browsers.

@Casey Crookston 2017-03-23 17:17:21

this works for me, even on mobile devices

@Stewart 2017-06-01 12:39:55

Is it possible without the 100% height on html and body?

@Steve Bennett 2017-11-30 01:36:58

Seems to work if you put 100vh on .box.

@Kuba Šimonovský 2018-02-20 12:04:00

doesn't work in safari 10 ! so be aware of using this approach

@Pebbl 2018-02-21 08:47:41

@KubaŠimonovský you'll need to give more information than "doesn't work". Loading the above example in Safari 10 (Mac OS X Yosemite) everything works as expected (afaics). However, flexbox is a large specification, so perhaps there is something not as supported as other browsers.

@Kuba Šimonovský 2018-02-21 09:24:24

@Pebbl okey, my bad.. I have yosemite 10.10 but for some reason I have safari 8.. I have no idea how is this possible because i thought I have safari 10.. so my apology.. Anyway, i had problem with flex-direction: column and flex: 1 on child in safari 10. because child didn't fill the remaining space of parent

@Ben Carp 2018-03-19 11:31:46

Can I use the flex property on the body element? Is there any reason why not? Why should we use flex:1 0 auto; or flex:1 1 auto; when we can simply use flex-grow: 1 or flex-grow: 0`?

@Jason Polites 2018-08-27 05:57:25

Seems to mostly work, but (in Chrome at least) the footer height doesn't change no matter what you set .row.footer height to be

@Pebbl 2018-09-04 23:05:06

@JasonPolites — the height of the footer will change to what you set if it has room to, if the page is full of content it will collapse. If you want a footer that doesn't collapse then set the flex-shrink to 0 rather than 1.

@Jason Polites 2018-09-06 00:07:59

@Pebble actually I want the opposite. I want the footer to be smaller even if the content is mostly empty. E.g. setting footer height in the above solution to 10px doesn't make it 10px no matter what the content is

@Pebbl 2018-09-06 23:18:37

@JasonPolites — I believe you are hitting into a different issue altogether then (not flexbox related). It is most likely because you are trying to set the footer to be smaller than the height of its own content. The above footer contains <p> tags which by default have additional margins, which are definitely pushing out more than 10px. If you remove the margins, or remove the <p> tags you will find you can reduce the height of the footer. To get it to 10px, you may have to reduce font-size or line-height; or the universal fix to crop elements overflow: hidden on the .footer elm.

@Anthony Brenelière 2016-08-25 16:13:25

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>

@nguyên 2016-05-22 03:20:04

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

code:

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

@bvdb 2019-01-22 11:52:54

In my opinion the cleanest solution. It's better than adding javascript, for sure. (but the answer was already posted in 2015 by somebody else)

@Danield 2013-06-06 11:20:33

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 } 

@Ian Boyd 2013-08-10 22:27:50

i was just pointed to the technique of css tables. Turns out the answer already was already in this answered question. This is the best solution; clean, elegant, and using the exact tool in the exact way it was intended. CSS Tables

@mlibby 2013-11-23 16:14:37

The fiddle code doesn't quite match the answer here. Adding html, body { height: 100%, width: 100% } seemed critical in my tests.

@Gone Coding 2014-02-24 17:32:15

An annoying features of CSS tables is exactly the same as with normal tables: If the content is too large they expand the cell to fit. This means you may still need to limit the size (max-height), or set the height from code if the page is dynamic. I really miss Silverlight grids! :(

@Mike Mellor 2016-05-13 16:40:33

You can always add an absolutely positioned container inside the tabel row element then set its width and height to 100%. Remember to set the position to relative on the table-row element as well.

@dwelle 2016-08-30 16:32:40

@MikeMellor doesn't work in IE11 though since it seems to ignore relative positioning on table-row element so takes the height of first-positioned ascendant that's not a table element.

@user1742529 2018-04-18 14:06:56

more complex similar solution: stackoverflow.com/questions/21222663/…

@Diego Perez 2018-10-02 11:11:59

This solution is not fully responsive: I'm trying it with a header which has a navbar and if you hit the menu toggler icon the behaviour is unexpected, it doesn't make the content to move down along with the menu.

@John Kurlak 2015-02-20 17:12:17

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:

HTML:

<div class="table container">
  <div class="table-row header">
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
  </div>
  <div class="table-row body">
    <div class="table-cell body-content-outer-wrapper">
      <div class="body-content-inner-wrapper">
        <div class="body-content">
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
        </div>
      </div>
    </div>
  </div>
</div>

CSS:

.table {
  display: table;
}
.table-row {
  display: table-row;
}
.table-cell {
  display: table-cell;
}
.container {
  width: 400px;
  height: 300px;
}
.header {
  background: cyan;
}
.body {
  background: yellow;
  height: 100%;
}
.body-content-outer-wrapper {
  height: 100%;
}
.body-content-inner-wrapper {
  height: 100%;
  position: relative;
  overflow: auto;
}
.body-content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

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

JSFiddle live preview

@Brandon Mintern 2016-07-08 14:26:32

Thank you!!! I tried all of the non-table, non-flexbox answers, and this is the only one that worked 100% correctly. One question: the original source only has a body-content-wrapper, and things seem to work just fine without the double wrapper (without any table-cells). Is there a problem with doing it that way?

@John Kurlak 2016-07-09 21:50:46

@BrandonMintern If you don't have the table-cells, it doesn't work in IE8 and IE9. (See comment in original article.)

@Brandon Mintern 2016-07-11 22:16:06

Yep, the cells are also required in IE10. Unfortunately, in IE10 and under, the .body height ends up being the same height as that set on .container. The vertical scrollbar is still in the right place, but the .container ends up getting stretched bigger than we want. When it is full screen, the bottom of .body is off the bottom of the screen.

@STeN 2011-08-06 03:30:33

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>

@Ormoz 2014-09-14 21:09:51

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

@Steve Bennett 2015-04-01 11:30:58

Wow, never heard of vh and vw units before. More info: snook.ca/archives/html_and_css/vm-vh-units

@Scott 2016-01-06 21:01:31

Unfortunately, this does not support IE8 :(

@Brandon Mintern 2016-07-08 13:44:01

I tried this approach, but the height: 100% on #content caused its height to match that of #page, ignoring #tdcontent's height altogether. With a lot of content, the scroll bar extends beyond the bottom of the page.

@Michael P. Bazos 2016-01-03 17:16:47

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

@Naeem Baghi 2018-01-01 13:22:59

main { height: 10px; flex: 1; overflow: auto }

@Puiu 2015-10-30 15:39:16

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

@Epirocks 2018-03-13 10:05:12

But 100vh sounds like all the height, not the remainder height. What if you have a header and you then you want to fill the rest

@Mr. Alien 2014-04-27 12:05:12

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

<header>100px</header>
<section>Expand me for remaining space</section>
<footer>150px</footer>

So your CSS should be

html, body {
    height: 100%;
}

header {
    height: 100px;
    background: grey;
}

section {
    height: calc(100% - (100px + 150px)); 
    /* Adding 100px of header and 150px of footer */

    background: tomato;
}

footer {
    height: 150px;
    background-color: blue;
}

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.

@Danield 2014-04-28 08:20:35

The OP said that the header could be an arbitrary height. So if you don't know the height in advance you won't be able to use calc :(

@Mr. Alien 2014-04-28 10:52:02

@Danield That's why I've mentioned fixed height :)

@jlyonsmith 2015-08-01 00:48:32

This is the solution that worked for me and did not require me to redesign my existing pages around flexboxes. If you are using LESS, i.e. Bootstrap, be sure and read the coderwall post on how to escape the calc() function so LESS doesn't handle it.

@jck 2018-04-25 16:09:28

Op said 'This could be an arbitrary height'. Arbitrary means decided by designer, thus fixed. This solution is by far the best one.

@zok 2015-02-27 18:21:05

A simple solution, using flexbox:

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

html, body {
  height: 100%;
}

body {
  display: flex;
  flex-direction: column;
}

.content {
  flex-grow: 1;
}

Codepen sample

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

@Jerph 2008-09-18 17:52:16

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>

@Vincent McNabb 2008-09-18 18:02:42

Already thought of this. But it doesn't work either. I'm just going to stick with a table because it works. Thanks for the update though.

@Arun 2013-04-27 11:45:48

Try this

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

@B_G 2011-06-20 09:36:23

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

@Yugal Jindle 2013-03-17 07:46:49

What if you don't know the height of the header ?

@Tonye - True Vine Productions 2011-10-17 14:00:39

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

@mlibby 2013-11-23 15:44:29

100% of what? If I try this I get a huge blank space and scrolling starts to happen.

@Jess 2014-09-18 01:44:57

100% of the viewport size maybe @mlibby. If you set your html and body to 100% height also, then the div can go 100%. With only a single div, the 100% will be relative to the div content. I didn't try it with a nested div.

@Martin 2015-07-01 10:43:41

It means 100% of the element's height (added as the element's padding), which makes it double the height. No assurance it will fill the page, and definitely not the answer to the question. It may as already notet actually fill more than the viewport.

@Romeno 2016-06-01 17:24:44

padding-bottom: 100% sets height +100% of parent container width

@mehdi.loa 2018-09-12 03:59:43

from w3school: Specifies a bottom padding in percent of the width of the element. w3schools.com/cssref/pr_padding-bottom.asp

@Thaoms 2012-02-20 09:21:45

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

@Neeson.Z 2015-05-14 08:13:05

The thing is if a user uses a large screen to review this page and your header's height is fixed exactly 100px which is smaller than 40% of current height, there will be a big blank gap between your header and body context.

@NICCAI 2008-09-18 08:16:50

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.

@Vincent McNabb 2008-09-18 09:22:12

That's what I suspected. However, the app will also work with Javascript turned off, so I guess I'll just keep using the table.

@Travis 2010-05-04 20:00:03

Vincent, way to stand your ground. I was looking to do the exact same thing and it appears not possible with css? I'm not sure but regardless none of the other tons of solutions do what you've described. The javascript one is the only one that works correctly at this point.

@Techsin 2013-11-17 08:55:26

what if window height changes

@Emeka 2013-12-26 15:55:07

@Techsin use jquery or the likes to bind to the window resize event: $(window).bind('resize orientationchange',doResize);

@kamii 2014-02-19 23:21:27

I mean...why are we not using calc in 2013?

@TMS 2014-04-17 09:32:50

The trouble with onresize is that it doesn't work. It won't catch resize of the inner content of the DOM tree, see stackoverflow.com/q/5532453.

@Algorath 2014-05-22 15:10:27

@TMS Why not add event listeners to the content that does resize?

@TMS 2014-05-26 15:12:31

@Algorath what event do you have in mind? The problem is there is actually no such event that would trigger on DOM change, see the linked question stackoverflow.com/q/5532453

@Gohan 2014-06-20 01:53:30

I got same problem, still no better ways?

@Mark Murphy 2015-02-20 14:29:10

Is this not a sound cross browser solution: stackoverflow.com/questions/18665171/…

@jkdev 2016-02-17 09:19:42

@MarkMurphy It depends. Are your website visitors still using IE 6/7, or have they upgraded?

@WasiF 2018-07-19 13:38:54

It would be nice if you have converted your description as code

@WilliamX 2018-11-14 00:24:26

height: calc(100vh - 400px); is a valid CSS style that does exactly what this post is about. All other solutions rely on having a fixed parent height or block display.

@Amiramix 2013-07-05 21:17:02

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>

@Vincent McNabb 2013-07-09 06:24:16

A good answer, which I upvoted, but unfortunately, does not work with IE8, which will still be around for a long time to come.

@Vincent McNabb 2013-07-09 21:31:54

Applications like Gmail use Javascript for the sizing, which is a better solution that CSS in most cases anyway.

@Amiramix 2013-07-09 21:37:44

I think they are using Javascript because there is no other good cross-browser CSS solution, not because it's better.

@Govind Rai 2016-09-25 05:45:38

@VincentMcNabb Works in IE8 w3schools.com/cssref/pr_class_display.asp. Just requires !DOCTYPE declaration. Never even knew about a table value for display attribute. Cool solution. +1

@Mikko Rantalainen 2013-05-03 10:55:31

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.

@htho 2012-09-14 08:02:34

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.

@Jerph 2008-09-18 06:01:58

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

@Vincent McNabb 2008-09-18 07:50:41

Close! Almost what I want, except I'm going to have other things positioned in the div... i.e. top: 0; will put something right below the header. I'll modify my question again, because you answered it perfectly, and still not what I want! I'll just hide the overflow as the content must fit.

@Casebash 2011-05-19 05:44:33

-1: This answer creates a div called content that covers the whole screen, not the rest of the screen

Related Questions

Sponsored Content

13 Answered Questions

[SOLVED] Div height 100% and expands to fit content

22 Answered Questions

24 Answered Questions

[SOLVED] How to make a div fill a remaining horizontal space?

3 Answered Questions

[SOLVED] Fill remaining vertical space with CSS using display:flex

  • 2014-08-02 18:15:57
  • Zilk
  • 122026 View
  • 130 Score
  • 3 Answer
  • Tags:   css layout flexbox

31 Answered Questions

[SOLVED] How to make a div 100% height of the browser window?

  • 2009-10-15 21:18:43
  • mike
  • 1670921 View
  • 1838 Score
  • 31 Answer
  • Tags:   html css css3 height

34 Answered Questions

[SOLVED] How to make div not larger than its contents?

  • 2009-01-16 16:03:07
  • George Snider
  • 1216798 View
  • 1794 Score
  • 34 Answer
  • Tags:   html css width

21 Answered Questions

[SOLVED] Make body have 100% of the browser height

  • 2011-07-11 18:50:56
  • bodyofheat
  • 725935 View
  • 685 Score
  • 21 Answer
  • Tags:   html css height

10 Answered Questions

[SOLVED] HTML table with 100% width, with vertical scroll inside tbody

11 Answered Questions

[SOLVED] CSS: Setting width/height as Percentage minus pixels

  • 2010-03-12 17:34:54
  • MegaMatt
  • 331002 View
  • 419 Score
  • 11 Answer
  • Tags:   css height pixels

26 Answered Questions

[SOLVED] Make Iframe to fit 100% of container's remaining height

  • 2008-11-28 08:23:48
  • Darkthread
  • 467187 View
  • 213 Score
  • 26 Answer
  • Tags:   html css iframe

Sponsored Content