CSS and 100% height

I have searched high and low for information on this topic, I have experimented again and again with very limited success. I wanted to share my findings in hopes that someday some poor soul will not have to go through the horror of trial and error.

My dilema even made it to the SXSW panel where Vertua partially tackled some of the issues people have with absolutely positioned layouts and gave a presentation on better CSS layout strategies.

The goal here is to create a 100% vertically stretching column with a background colour (not an image) that will stretch to 100% height regardless of the amount of content, (ie a single line of text, or 100’s of lines).

If you are pressed for time or are tired of wasting time researching this issue my conclusion thus far is that it certainly isn’t easily accomplished. Below outlines the best methods I have found thus far.

Courtesy of Position is Everything
Equal Height Columns

The Magic

The basic method works like this:

1. Blocks which will act as columns must be wrapped in a container element
2. Apply overflow: hidden to the container element
3. Apply padding-bottom: $big_value [2] to the column blocks, where $big_value is a large enough value to guarantee that it’s equal to or larger than the tallest column
4. Apply margin-bottom: -$big_value to the column blocks

What happens is that columns really become as tall as the content they contain plus $big_value thanks to the padding-bottom. The negative margin-bottom brings the flow of the document back to where the same point as where the padding-bottom began, and the overflow: hidden on the containing element chops off the overflow[3]. Consequently the columns’ presence on the page only appears to be the height of the containing element and any background colour (or image for that matter) applied to the columns displays for that height. Most crucially, the height of the page reflects what appears to be on the page and does not dissappear into the scrolling distance.

Remarkably, IE Win doesn’t actually need the overflow: hidden, but it causes no problems so there is no need to hide it.

Beware though, browsers don’t let you throw arbitrarily large values at them. They have limits. Exceed that limit and the columns will expand to the padding-bottom value and you’ll end up wiuth some pretty long pages. Fortunately, we know the number of that limit (which is actually provided by Safari which is the most conservative browser in this matter): 32767px.

The CSS:

#wrapper {
#block1 {
padding-bottom: 32767px;
margin-bottom: -32767px;
#block2 {
padding-bottom: 32767px;
margin-bottom: -32767px;


<div id="wrapper">
<div id="block1">Block 1</div>
<div id="block2">Block 2</div>

Note: The above example is the very bare bones, please read the entire article to get browser specific code.

Even this method does not accomplish 100% height if the content doesn’t already stretch to more than your viewport. It does however work well for creating equal height columns and when the content does fill more than the viewport it does appear to be 100% stretching. IE: No more “cut off”.

Other things I have tried which gave me limited or no success:

1) A 100% height wrapper around an absolutely positioned 100% height column. This works only until the content runs outside the viewport. The column appears “cut off” and the content runs out over it.

2) Min-Height – I simply had zero luck with this

3) Wrapper with Overflow and Floated Columns – Again I get “cut off” after the viewport.

4) Every height, min-height, wrapper, no wrapper, float, position and even doc-type scenario I could think of.

There have been rumors of display:table; coming to the rescue in the future but as of now I have yet to find the perfect solution. This also means that unfortunately that some people may be forced to remain with tables for certain layout methods.

I really look forward to discussing this particular quirk (no pun intended) with readers.

3 comments on “CSS and 100% height

  1. Steven says:

    I too have been breaking my head over this problem. I have tried a number of solutions, none of them are satisfactory. Here are the options:
    1. Set the height using javascript. The drawbacks to this are that not all users have javascript enabled and not all browsers handle javascript the same.
    2. Use table display. This doesn’t work in IE
    3. “Faux columns” using tiled backgrounds. Doesn’t work if you have a gradient background (my problem)
    4. Use a large value for padding-bottom and a large negative value for margin bottom. This works well, but if your divs have a border, the border is cut off the bottom. I couldn’t find a workaround for the border problem, so this is not an option for me.
    5. The “column swapping” method. It is very sensitive to the content of the divs, and has a problem with borders, but perhaps someone else can get it to work for them. There is a nice explanation of the method at http://www.satzansatz.de/cssd/columnswapping.html
    I’d be interested to hear of any other methods, or if someone has a workaround for the problems in one of the methods I tried.

  2. Sharon says:

    With a slight modification the overflow, floated column seemed to work for me. The modification was adjusting the padding to be greater than the negative margin.

    #wrapper {
    position: absolute;
    width: 100%;
    overflow: hidden;
    #leftcol {
    padding-bottom: 6000px;
    margin-bottom: -5500px; /* note 500px diff */
    #maincol {
    padding-left: 110px;

    The HTML:

    Block 1
    Block 2

    Note that I don’t have a border on either the left or main column div, but I do have a background on the left column without being cutoff no matter what amount of text is in the maincol block. Note that the lefcol only contains limited text … there were some issues when text in the leftcol exceeded the height of the maincol.

    I never would have been able to find what works for me without reading your tip. Thanks!

  3. Nuno Godinho says:

    Don’t know if you already seen this link http://www.xs4all.nl/~peterned/examples/csslayout1.html, but this works pretty good.

Leave a Reply