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 and Opera. These browsers apparently give 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 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. 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.

    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.

    MethodIE WinIE MacMozillaOperaSafari
    'Quirks mode'
    Example
    Yes Yes Yes Yes No
    'Strict mode'
    Example
    No Buggy No No No
    'Strict mode' + body 100%
    Example
    Yes Buggy No Yes No
    'Strict mode' + body + html 100%
    Example
    Yes Buggy Yes Yes Yes

    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.

    Contents