100% height

Explorer 5 Mac has serious problems.

On this page I explain how to give an element a height of 100%. People seem to think this is a very difficult problem, but it isn't.

First of all, let's define the case more clearly: I want an element to stretch 100% of the height of the viewport (browser screen). The most obvious start is:

div#test {
	height: 100%;
}

Now this works in all browsers but Safari: the div stretches from top to bottom.

There's a catch, though: it only works when the browser is in 'Quirks mode' (= no doctype). As soon as you switch the browser to 'Strict mode' things get far trickier.

'Strict mode'

According to the specs height: 100% means: "give the element a height of 100% of the containing block's height." In 'Quirks mode' this rule works to our advantage. The containing block of the div is the body, and the body itself stretches 100% of the viewport. So we tell the div to stretch 100% of 100% and it works.

Of course 'Strict mode' is far more complicated. Here the body doesn't stretch 100% of the viewport. Instead, it stretches only as much space as is necessary for containing its elements. Besides, in its turn the body has a containing block: the html tag.

From the specs, this behaviour is understandable. The natural height of the body and html elements is (should be) auto, which means: as much as it needs.

So when we add a doctype to switch the browser to 'Strict mode' our solution doesn't work any more. Body and html stretch up to allow for the actual content of the div, but not any further. So the height of the div is strictly limited to the height it needs to display its content.

The solution to this problem is simple: we need to give the body and/or html element a height, too! It was Stephen Caudill who told me and I gladly use and extend his idea.

When we add:

body {
	height: 100%;
}

to our CSS, the example once again works in Explorer Windows. Apparently it gives the html element (but not the body element) the same height as the viewport. If we stretch the body to cover 100% of the viewport, our test div also stretches up until its height is equal to the viewport height.

As to Mozilla and Safari, they do not react. Fortunately, this is simple to solve, too:

html,body {
	height: 100%;
}

and the example works in all browsers. Apparently Mozilla, Opera and Safari see the viewport as the containing block of the html element, so stretching the html element to cover the viewport also stretches up its child elements.

Solution

So this is the solution:

html,body {
	height: 100%;
}

div#test {
	height: 100%;
}

Compatibility

Unfortunately Explorer on Mac makes a mess of all examples but the 'Quirks mode' one. For unknown reasons it displays both divs with far too much width, not the few pixels caused by box model problems.

Therefore I'm forced to conclude that the only safe way to get this effect to work in Explorer Mac is leaving out the doctype. On the other hand, if you leave it out it'll never work in Safari. So which Mac browser should it work in?

A further problem is that Explorer on Windows 'Strict mode' follows the W3C box model. In my example it stretches the div slightly beyond the bottom edge of the screen because the 100% height excludes the borders. Of course it depends on your design how much this matters.

All in all I myself will go for the 'Quirks mode' solution. But anyone can use the solution he or she likes best.

Method Explorer Windows Explorer 5.2 Mac Mozilla 1.4 Safari 1.0 Opera 7.20
'Quirks mode'
Example
Yes Yes Yes No Yes
'Strict mode'
Example
No Buggy No No No
'Strict mode' + body 100%
Example
Yes Buggy No No No
'Strict mode' + body + html 100%
Example
Yes Buggy Yes Yes Yes

On the Viewport Experiments page I try to embed these test results into a larger whole.

Other situations

Please note that the solution presented on this page is only meant to give an element the same height as the viewport. You cannot port this height: 100% code to other situations.

For instance, if you want to make an element as high as the entire page (whatever this height may be) you're out of luck. Although it might seem simple the specs (and the browsers' unthinking conformance) make this completely impossible.

The spec says: "If the height of the containing block is not specified explicitly (i.e., it depends on content height), the value is interpreted like 'auto'."

This means that if you do not define any height at all for the containing block, a percentual height of any contained block doesn't work: the block becomes once again exactly as high as it needs to be.

Even though this rule may in a few cases save the browser work in calculating the correct heights of elements, I still think that it is far too restrictive and it's caused by bad thinking on the part of the standard makers and the browser vendors. Counter-intuitive and unnecessary rules like this one make our beautiful CSS too hard to work with.