Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 788
Vincent McNabb Avatar asked Sep 18 '08 05:09

Vincent McNabb


People also ask

How do you find the remaining height of a viewport?

so you need to do html {height:100%} then it is usable for body {height:100%} and from here . root will apply those 100% from viewport .


2 Answers

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.

like image 89
Pebbl Avatar answered Oct 02 '22 03:10

Pebbl


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.

like image 25
NICCAI Avatar answered Oct 02 '22 03:10

NICCAI