Categories
css html html-table

Make a div fill the height of the remaining screen space

2505

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.

8

  • 46

    For anyone stumbling here in the future, you can get the desired table layout in most browsers, without the table mark-up, by using display:table and related properties, see this answer to a very similar question.

    – AmeliaBR

    Jan 20, 2014 at 2:23

  • 4

    I’ve tried to recereate your setup – jsfiddle.net/ceELs – but its not working, what am I missed?

    Apr 14, 2014 at 12:12


  • 7

    @Mr. Alien’s answer is simple and useful, check it out http://stackoverflow.com/a/23323175/188784

    – Gohan

    Jun 20, 2014 at 3:30


  • 5

    Actually, what you describe does not work, even with tables: if the content takes more vertical space than the screen height, the table cell and the whole table will expand beyond the screen bottom. Your content’s overflow:auto will not make a scrollbar appear.

    – Damien

    Jul 1, 2014 at 20:00

  • @GillBates it will work after you specify height of parent element look at jsfiddle.net/ceELs/5

    Sep 30, 2014 at 9:45

1546

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.

7

  • 10

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

    – Erdal G.

    Nov 15, 2015 at 9:36

  • 16

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

    May 10, 2016 at 18:40

  • 93

    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.

    – przemcio

    Jul 13, 2016 at 21:55

  • Navbars with transparency doesn’t work. The alpha channel in rgba has no effect at all and fixed header/footer can only have solid background colors.

    – Shahriar

    Nov 26, 2021 at 14:51


  • So to implement it down in the DOM tree, I need to set height: 100% from the body through all div to my required div?

    – baruchiro

    Apr 11 at 6:51

268

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.

2

  • 3

    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.

    Sep 18, 2008 at 9:22

  • 6

    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.

    – Travis

    May 4, 2010 at 20:00

187

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>

1

  • 84

    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…

    Mar 4, 2012 at 17:16