tags:

views:

25654

answers:

7

I am currently 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:

#page {
  height: 100%; width: 100%
}
#tdcontent {
  height: 100%;
}
#content {
  overflow: auto; /* or overflow: hidden; */
}

HTML:

<table id="page">
  <tr><td id="tdheader">
    <div id="header">...</div>
  </td></tr>
  <tr><td id="tdcontent">
    <div id="content">...</div>
  </td>
</table>

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

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 it's 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.

A: 

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?

Bruce
That's not quite what I want to do. I want the content `div` to fill the remainder of the screeen, not to actually be the same height as the screen.
Vincent McNabb
That appears to be what my example does, at least when I try it. Do you not see that behavior?
Bruce
Try putting a table inside the content, that is at size 100%. It will not work.
Vincent McNabb
+3  A: 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<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.

Jerph
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.
Vincent McNabb
A: 

I think you probably need to look at the min-height property.

The following tutorials might help:

100% Height Layout Using CSS

Create Pages that Fill the Browser with CSS

I've just tested the following and it works cross-browser. No need for Javascript as the accepted answer suggests. What's the problem with the no-JS solution?

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <style type="text/css">
  body, html {
    height: 100%;
  }

  #wrapper {
    min-height: 100%;
    background-color: red;
    border: 1px solid black;
  }

  #header {
    background: blue;
    height: 100px;
  }
  </style>
</head>

<body>
<div id="wrapper">
  <div id="header">header</div>
  <div id="content">content</div>
</div>
</body>
</html>
Charles Roper
I tested it by adding a table at 100% height inside the div. It made the table the same height as the screen. Not what I wanted.
Vincent McNabb
That results in the `#wrapper` element occupying the height of the window, but I believe Vincent is looking to have the `#content` element fill the remaining vertical height in the window. If you move your `background-color: red` declaration to a CSS rule for the `#content` element you'll see this solution doesn't work.
Simon Lieschke
+6  A: 

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.

NICCAI
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.
Vincent McNabb
There seem to be several solutions here that don't rely on JS. Why no go with one of them instead?
Charles Roper
Because non of the solutions work as per the description.
Vincent McNabb
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
+1  A: 

Try this, it should work in all browsers:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
    <title>Test</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style type="text/css" media="screen">
    * { 
     margin: 0; 
    }

    html, 
    body { 
     height: 100%; 
    }

    #wrapper {
     min-height: 100%;
     height:     auto !important;
     height:     100%;
     margin:     0 auto -44px; /* -44px being the size of the footer */
    }

    #header { 
     height: 86px; 
    }

    #footer, 
    #push {
     height: 44px; 
    }
    </style>
</head>
<body>
    <div id="wrapper">
     <div id="header">header</div>
     <div id="content">content</div>
     <div id="push"></div>
    </div>
    <div id="footer">footer</div>
</body>
</html>
daniels
Works great in Safari, Chrome, Firefox. Haven't tried IE.
Leopd
Looks nice but the poster said he doesn't know the height of the header...
Emtucifor
+1  A: 

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"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<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>
Jerph
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.
Vincent McNabb
A: 

it's not work like I think, if I insert an iframe with a webpage or picture, the will over load the normal size of the window.

thang