100% High DIVs and 3-Column Layout

Home

Several members at Webmaster World have asked if there was a method to assign 100% height to <div>'s used as left and/or right navigation menus. In some cases, members also wished to assign background-images to their div's that would always display at 100% of the resized browser window.

Most attempts to accomplish this were made by assigning the property and value: div{height:100%} - this alone will not work. The reason is that without a parent defined height, the div{height:100%;} has nothing to factor 100% percent of, and will default to a value of div{height:auto;} - auto is an "as needed value" which is governed by the actual content, so that the div{height:100%} will only extend as far as the content demands.

The solution to the problem is found by assigning a height value to the parent container, in this case, the body element. Writing your body stlye to include height 100% supplies the needed value.

body { 
margin:0;
padding:0;
height:100%;
}

Now when height:100%; is applied to divs (or other elements) contained withing the body, the height percentage has a containing (body) value to work with.

The following example is a three column, liquid layout with 100% height assigned to both flanking divs. Background images can be assigned to these divs and will render at 100% of the window height.

Either copy-and-paste the following code into a new file, or click here to see a ready-made example.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//Dtd XHTML 1.1//EN"
"http://www.w3.org/tr/xhtml11/Dtd/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > 
<head> 
<title>One Hundred Percent Height Divs</title> 
<style type="text/css" media="screen"> 
  body { 
    margin:0; 
    padding:0; 
    height:100%; /* this is the key! */ 
  } 
  #left { 
    position:absolute; 
    left:0; 
    top:0; 
    padding:0; 
    width:200px; 
    height:100%; /* works only if parent container is assigned a height value */ 
    color:#333; 
    background:#eaeaea; 
    border:1px solid #333; 
  } 
  .content { 
    margin-left:220px; 
    margin-right:220px; 
    margin-bottom:20px; 
    color:#333; 
    background:#ffc; 
    border:1px solid #333; 
    padding:0 10px; 
  } 
  #right { 
    position:absolute; 
    right:0; 
    top:0; 
    padding:0; 
    width:200px; 
    height:100%; /* works only if parent container is assigned a height value */ 
    color:#333; 
    background:#eaeaea; 
    border:1px solid #333; 
  }
  #left p { 
    padding:0 10px; 
  } 
  #right p { 
    padding:0 10px; 
  } 
  p.top { 
    margin-top:20px; 
  }
</style>
</head>
<body> 
<div id="left"> 
  <p class="top">This design uses a defined body height of 100% which allows setting the contained left and right divs at 100% height.</p>
  <p>This design uses a defined body height of 100% which allows setting the contained left and right divs at 100% height.</p> 
  <p>This design uses a defined body height of 100% which allows setting the contained left and right divs at 100% height.</p>
</div> 
<div class="content"> 
  <p>This design uses a defined body height which of 100% allows setting the contained left and right divs at 100% height.</p>
</div> 
<div class="content">
  <p>This design uses a defined body height which of 100% allows setting the contained left and right divs at 100% height.</p>
</div> 
<div class="content">
  <p>This design uses a defined body height which of 100% allows setting the contained left and right divs at 100% height.</p>
</div> 
<div id="right">
  <p class="top">To solve an inheritance issue displayed in div #right as rendered in Opera, class p.top using margin-top:20; is applied to the first paragraph of each outer divs.</p> 
  <p>This design uses a defined body height which of 100% allows setting the contained left and right divs at 100% height.</p> 
  <p>This design uses a defined body height which of 100% allows setting the contained left and right divs at 100% height.</p>
</div>
</body>
</html> 

Tiling backgrounds may also be deployed:

 #right { 
    position:absolute; 
    right:0; 
    top:0; 
    padding:0; 
    width:200px; 
    height:100%; /* works only parent container is assigned a height value */ 
    color:#333; 
    background:url(images/mytile.gif) repeat; 
    border:1px solid #333; 
  }

A three column liquid layout was used for demonstration purposes, the 100% height can be applied as required.

The above three column layout will not display properly in Netscape 4.x because of the position:absolute; right:0; styles of the div #right. Remember to protect Netscape 4 from styles it cannot understand by using the @import rule.

The above has been tested in Opera6, IE6, and Mozilla 1.1 - it should work in most modern browsers.

Have fun!

XHTML + CSS + WebStandards = FREEDOM!

- papabaer ;)

################################

If you put that xml declaration under the Doctype it will still validate and won't trigger IE6's 'quirks' mode? The design may not suffer from being in 'quirks' mode but it's a point worth noting.

Nick

################################

Works okay in IE5 (but not konqueror). A passable workaround for that naughty little NS4 fella.... dump all the styles in a sheet but change the #right div to this:

#right { float: right; position: absolute; top: 0; padding:0; width:200px; height:100%; /* works only if parent container is assigned a height value */ color:#333; background:#eaeaea; border:1px solid #333; }

then @import the original #right and everybody's happy

Nick