tags:

views:

575

answers:

4

Hi, I'm really trying to work with div's and I can't seem to get the equivalent to the following simple table layout:

<!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" xml:lang="en" lang="en">
<head>
<title>Table example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
html, body {height: 100%}
.content {width: 750px; vertical-align: top}
</style>
</head>
<body style="margin: 0; padding: 0">
<table style="height: 100%; width: 100%; border-collapse: collapse">
<tr style="background-color: #666666">
<td></td>
<td class="content" style="height: 100px"><h1>Header Content</h1></td>
<td></td>
</tr>
<tr style="background-color: #BBBBBB">
<td></td>
<td class="content" style="background-color: #FFFFFF"><h1>Main Content</h1></td>
<td></td>
</tr>
<tr style="background-color: #666666">
<td></td>
<td class="content" style="height: 100px"><h1>Footer Content</h1>
</td>
<td></td>
</tr>
</table>
</body>
</html>

The important elements that I want to preserve:

1.) Any real content is fixed width. (in this case, 750px)

2.) The header and footer backgrounds expand to 100% of the page width.

3.) The main content background does not expand horizontally, but does expand vertically to fill the area between header and footer.

4.) The footer is always at the bottom of the page even when the main content is not very tall.

I've tried a number of strategies and found at least 2 different ways to keep the footer at the bottom of the page using divs. Unfortunately, if the main content is in a div, there's doesn't seem to be any way to make it expand vertically to fill the space between the header and footer on short pages.

Edit: Changed the example to show that it works even when not in quirks mode. The above validates.

Edit 2:

I've found a way to do this for the most part with javascript. So, I guess my question is: how do I do this without javascript. Here's what I'm using (which I'm sure only works in firefox, but I could fix that up):

<script type="text/javascript">
function changeDiv() {
    document.getElementById("content").style.minHeight = document.body.clientHeight - 200 + "px";
}
changeDiv();
window.onresize = changeDiv;
</script>

"content" would specify the main content div I want to expand.

A: 

Your real question seems to be "how do I get my main div to expand, and my footer to go to the bottom of the page."

And the answer is going to be: you can't do it with tables either, at least not if you use a doctype that specifies HTML 4.0 transitional or above. Yes, it works without a doctype, but that's because browsers enter their "quirks mode" in that case.

I believe you can do it with absolute positioning, and you've probably seen examples. Personally, I'd look more at an approach that uses fixed positioning for the footer, with a larger z-order so that it renders on top of the content, and then use a gradient effect to make the main content disappear behind it. Here's an example (created by someone far better than me): http://www.designbyfire.com/

kdgregory
Your "real question" characterization is correct except if the main content background was the same as the body background, it wouldn't matter. Also, it works with doctype html 4.0 transition is you add "html, body {height: 100%}".
btmorex
What do you mean with you can't do with tables either? Simply specify html, body, table { height: 100% }; then specify fixed heights for the header and footer row. Please correct this in your post.
facildelembrar
A: 

Here's my attempt. Seems OK on FF3 and IE8:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
<head>
<style type="text/css">
html, body { padding: 0; margin: 0; }
div { padding: 1px; }
#wrapper, #wrapper-top, #wrapper-bottom { position: absolute; left: 0; right: 0; width: 100%; }
#wrapper-top { background-color: #666; height: 100px; top: 0; }
#wrapper-bottom { background-color: #666; height: 100px; bottom: 0; }
#wrapper { top: 100px; bottom: 100px; background-color: #DDD; }
#header, #content, #footer { width: 750px; margin: 0 auto; height: 100%; min-height: 100%; }
#content { background-color: white; }
</style>
</head>
<body>
<div id="wrapper-top">
  <div id="header"><h1>Header Content</h1></div>
</div>
<div id="wrapper">
  <div id="content"><h1>Main Content</h1></div>
</div>
<div id="wrapper-bottom">
  <div id="footer"><h1>Footer Content</h1></div>
</div>
</body>
</html>

Note: The DOCTYPE is important and forces compatibility mode in IE.

cletus
Actually, that's fairly close. Unfortunately, when the main content is longer than the page height, footer is still at the bottom of the window, as opposed to the bottom of the content.
btmorex
Try using FooterStick to combat this... see my answer.
alex
A: 

For getting a footer to stick to the bottom of the page, depending on if content is larger than viewport height, or if content doesn't quite reach the bottom (but you still want the footer to appear at the bottom) try implementing FooterStick.

alex
alex, I believe I've tried that method. The problem is that the "wrapper" div expands, but the actual content div doesn't. So, in my example, you just get a bunch of vertical space filled with the body's background color. If the background color = content bg color, it works, but otherwise it doesnt.
btmorex
what if you set the content div to height: 100% ?
alex
A: 

This can be done in non IE browsers. But on IE (at least IE7-), you need to use tables and preferably conditional comments.

I haven't took the time to test, but try this and see if it works:

On html, use a strict doctype. Preferably xhtml like this

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;

and put this in the body:

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

And on css:

div.header,
div.content,
div.footer {
    position: absolute;
}

div.header {
    top: 0;
    height: 20px;
}

div.footer {
    bottom: 0;
    height: 20px;
}

div.content {
    top: 0;
    bottom: 0;
    /*can't remember if it was margin or padding, if one doesn't works, try the other*/
    margin-top: 20px;
    margin-bottom: 20px;
}
facildelembrar