Make a Container Stretch the Full Length of a Web Page with CSS

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.

[Link] Comments: [18] Project: [HTML/CSS Practice]

Hi, thanks for a usefulp tip. Have been trying to sort the same problem myself for a little while and also not had much luck on Google. BTW, for me at least there seems to be an issue with the NWSC site on Opera (Windows), some of the imagery and headings etc are not showing. Only noticed myself as I use Opera ocassionally to save site info.

Marcus 19 Sep 2005

Hi Marcus,

Glad to have helped in some small way, and thanks for the report on NWSC in Opera. I will have to attept a fix for that when I next find free time!

ARJ roceal@jngm.net 19 Sep 2005

Very Impressed in this article.

I am at Avalon Beach, NSW.

Could you contact me and tell me how much you would charge to do a cssjob for me It is similar to -
Make a Container Stretch the Full Length of a Web Page with CSS - and I have seen the one with images butI think that this is a bit different.There are three container. Col 1 with menu but I need the BG-Image to stretch with the content when the content stretches more than 100%. Col 2 is a tile and I need its BG-image to do the same when the content stretches more than 100%.

Can you help.
I am prepared to pay.

Keren

Keren keren@muir.net.au 27 Oct 2005

Hi Keren,

There's no need to pay me, really. The solution is pretty simple. Just copy the example I used above, but set the background-image attribute on your columns in the CSS. That's all there is to it.

ARJ roceal@jngm.net 28 Oct 2005

Thanks for the good article! I've been looking through books and search engines and finally you gave me something clear and actually works. keep up the good work.

michael 30 Dec 2005

I've tried this now on one of my pages, yet the drop shadow fails to continue down. It stops at the end of the page, until I make my screen 1600x1200, because then the text doesn't go over the bottom edge. Obviously this isn't a solution hahaha. I'm struggling to understand what you did with the shadows to make them continue the length of the page.

(meant to go 100% page down, but only does screen)
(this however stretches 100% of content)
...
...

...
...

...
...
...
...
...
...

(meant to go 100% page down, but only does screen)

I'm not sure if you can help by looking at this minimal code, but any help would be GREATLY appreciated.

Francois francois@lightbulb.co.za 17 Feb 2006

Oops, looks my code got eaten. Hmm.

Francois francois@lightbulb.co.za 17 Feb 2006

Hi Francois,
I filter out most HTML tags in my comments to try & prevent spammers. Feel free to email me with questions though.

ARJ roceal@jngm.net 21 Feb 2006

nice idea. But it's sad that you have to use position:absolute to center the div. I think this is a more clean way to center... http://flumpcakes.co.uk/css/center-div-ie

But then your tip doesn't work anymore :-/

Skooter 15 Mar 2006

Hi Skooter,

Thanks for dropping by. I guess I'm not really sure what's "sad" about absolute positioning? I suppose that it does require more CSS rules than your example-- but it gets the job done!

ARJ roceal@jngm.net 15 Mar 2006

What's wrong with using tables? css supports them, and they make layout pretty easy if you don't abuse them.

Russ rpuskarcik@myway.com 21 Aug 2006

Russ-- that argument is covered elsewhere and more eloquently by others. It is well-travelled territory at this stage. I suggest you start at www.zeldman.com.

ARJ roceal@jngm.net 21 Aug 2006

I had the same problem with a background i wanted to put in the main container on top of the body background. The background had a transparent shadow which doubled if 2 layers "touched" so after 10 hours of silly time waste i put all the page in a and found peace of mind. Yeah i'm not a table fan too but i don't consider problematic table use a single page container.

Jason Dean thejasondeanatyahooetcetc 08 Sep 2006

A very useful article, thanks. But the links to the examples seem to be broken.

Ccop 12 Nov 2006

Oops. Fixed the example links.

ARJ roceal@jngm.net 13 Nov 2006

Seems pretty simple. Thought there were surely be a more advanced fix for this be I guess the simple solution is the best for right now. Wish there was a way with having to use to separate elements but whateva. Thanks.
Using it here. http://www.quicksilvertrucks.com/test.php

TFiggs taltonfiggins@gmail.com 28 Nov 2006

The same can be done much simpler:

html, body {
height: 100%;
}
#container { /* div you want to stretch */
min-height: 100%;
}

OB nah@gmail.com 21 Mar 2007

Er... OB, perhaps you should take a second look at Example 2? That's exactly what the style definitions are there...

ARJ roceal@jngm.net 26 Mar 2007