Make a Container Stretch the Full Length of a Web Page with CSS
15 May 2005
Oftentimes I do little side web projects for friends and family, and I just recently finished one. The design they wanted involved a pale centered column of content with shading on either side that stretched the full height of the screen. This kind of layout would have been pretty simple to accomplish with tables using Microsoft Internet Explorer, but I wanted to keep up with current web development standards and keep everything as compliant as I could. Turns out this was really hard to figure out!
Perhaps the Oracle of Google failed me, or perhaps I just wasn't using the right search terms, but I couldn't find any resources out there that gave me a good working example, so I'm providing that here. The result seems to work OK in Firefox, Safari (there are other problems viewing this site in Safari, but the full height issue seems to render OK), and MSIE.
So you want some kind of container (I'm using <div>, but you can use anything that can be absolutely positioned, I think) that stretches the full height of the screen. Easy! Just set the height to 100%, right? Well, not quite. Simply setting the CSS height attribute doesn't work if the content inside your container extends past the height of the "viewport"-- if you have to scroll down, you'll see that the background colour of your container doesn't continue past the bottom of the initial viewable area when the page loads. The example below demonstrates what I mean with some code.
- Example 1: A container with height set to 100% looks OK as long as the text isn't too long.
- Example 2: But as soon as the text's height exceeds the viewable area, there's a problem.
So how about we don't set the height attribute at all? Well, this is OK too, except when the content in your container is too short to reach the bottom of the screen. This is pretty obvious, but I also demonstrate it in the example below.
- Example 3: Clearly we don't want to leave the default height on the container-- if the text is too brief, it won't stretch to the full height of the viewable area.
One workaround is to just create a background image that repeats vertically. This isn't too bad, but then you'll need a fixed width column in the middle. In most cases there's nothing wrong with this solution-- however, I really wanted a fluid layout, something that looked good and scaled well no matter what resolution was being used to view it, down to a minimum of 800x600. So a fixed-width centre column in my layout just wasn't going to to cut the mustard.
My solution, then, was to combine the two methods explained above. I used two containers: one, absolutely positioned, had its height attribute set to 100% and would stretch to the bottom of the page when the content was short. Above it on the z-axis would be another container that held the text itself and had no height attribute set. Its height would shrink and contract according to how much text it held-- if the text caused you to scroll down to the bottom, this container would continue on down until the very bottom, keeping the background colour consistent no matter how much text showed up.
- Example 4: A demonstration of the technique with a lot of text.
- Example 5: An example of the technique showing a small amount of text.
One thing I haven't mentioned yet was the shading I wanted to show up on either side of the container. I created a small image that would look like a drop shadow for either side of the main column. I needed one strip of vertically-repeating shading to show up on the left and right of the page.
I couldn't set this image as the background image of the main container, because I could only use one image for the background. I needed at least one extra container to just hold the shadow image-- but that left me back at the beginning of my problem. How could I get the container for the shadow to match the height of the main container?
It turns out I needed four extra containers-- two for each side. Two of the containers would be parent containers of the main content, and would stretch down as far as the text did. The other two were absolutely positioned and set with a height attribute of 100%. These would stretch down as far as the inital view of the page when it loaded. I used four containers in this way to help keep the symmetry of the page. Any other way was too difficult to make sure that everything lined up with the right widths.
Although I don't think I am the first to stumble across this technique, I did find it pretty useful. Any time I'd like to have multiple columns with different background images or colours that stretch all the way down the page, all I have to do is add one extra empty div. When compared to creating a table layout, if you count all the extra <tr> and <td> tags you need to define the table, one extra set of tags seems a small thing. The CSS needed for the actual layout itself is pretty minimal.