This article originally
appeared in the Design & Usability Tactics newsletter. Click
here
to subscribe automatically.

Many Web sites use some variation of
a basic three-column page layout. A typical layout often includes a full-width
header at the top of the page, then the three-column section, which is composed
of a center column for the main content, with side columns for navigation links
and sidebar items. A full-width footer at the bottom of the page rounds out the
basic layout.

My article, “Use CSS floats to
create a three-column page layout,”
describes a basic technique for creating
a three-column page layout. And I offer some refinements to the technique in
last week’s article, “Raise
text relevance by rearranging a three-column layout.”

One of the challenges of working
with a multiple-column layout is how to get background colors in each of the
columns to fill the full column height. It’s not a problem in page designs
where all the columns have the same background color, but creating separate
colors for each column is more problematic.

The trouble is that divs expand
vertically just enough to accommodate their contents. So, the obvious tactic of
assigning a background color to the div, corresponding to a page column,
doesn’t have the desired effect of filling the full column height with that
color. Instead, the color stops at the end of the div’s content.

Using a wrapper div to create a
background color for the shorter column (see last week’s article) is an
effective solution when you can predict which column will be the longest; but
creating a three-column layout that can accommodate different combinations of
column lengths requires a different approach.

Start with a three-column liquid layout

The basic technique for creating a
three-column liquid layout with CSS is to use floats to push the outer columns
out to the left and right sides of the browser window and allow the main
content to flow up into the gap in the middle, between the outer columns.
Setting the left and right margins for the middle column confines the main
content to a nice vertical column instead of spreading out into the side
columns. The side columns are each a fixed-width, but the center column is free
to expand and contract with changes in the browser window, making this a liquid
layout. (This technique is described in more detail in the previous column.)

Here’s the example code for a
three-column layout with full-width header and footer, as shown in Figure A.

First, the CSS styles:

body {
    margin: 0px;
    padding: 0px;
}
div#header {
    text-align: center;
    background-color: #CCCCCC;
    height: 60px;
    margin: 0px;
    padding: 1px;
}
div#navcol {
    padding: 10px;
    width: 130px;
    float: left;
}
div#main {
    padding: 10px;
    margin-left: 160px;
    margin-right: 160px;
}
div#sidecol {
    padding: 10px;
    width: 130px;
    float: right;
}
div#foot {
    border-top: solid #000 1px;
    background-color: #CCCCCC;
    padding: 10px;
    text-align: center;
    clear: both;
}

And, here’s the XHTML markup. (For
the sake of brevity, I show the contents of both side column divs as simple
unordered lists, and abbreviate the main content and footer text.)

<body>
<div id=”header”>
    <h1>Header Text</h1>
</div>
<div id=”navcol”>
    <h4>Nav Column</h4>
    <ul>
        <li>Let me not to the marriage of true minds</li>
        <li>Admit impediments; love is not love</li>
        <li>Which alters when it alteration finds</li>
        <li>Or bends with the remover to remove</li>
        <li>Oh, no, it is an ever fixed mark</li>
        <li>Let me not to the marriage of true minds</li>
    </ul>
</div>
<div id=”sidecol”>
    <h4>Starboard Side Column</h4>
    <ul>
        <li>Let me not to the marriage of true minds</li>
        <li>Admit impediments; love is not love</li>
        <li>Which alters when it alteration finds</li>
        <li>Or bends with the remover to remove</li>
    </ul>
</div>
<div id=”main”>
    <h2>Main Content</h2>
    <p> That looks on tempests … taken.</p>
    <p>That looks on tempests … taken.</p>
    <p>If this be error … height be taken.</p>
    <p>That looks on tempests … remove.</p>
</div>
<div id=”foot”>
    <p>Footer text goes here. … </p>
</div>
</body>

Figure B
shows the result of adding background colors to each of the column divs
(navcol, sidecol, main). However, this isn’t the effect we’re looking for.

Adding column backgrounds

The solution is to add a couple of
divs as containers for the column content divs, and use these containers to
create the column backgrounds. One div (column2) creates two columns with a
combination of a background image and a background color; the other div (column1)
creates the third column with another background image. The background images
are small GIF files, one-pixel tall by whatever width you need to create the
column width (in this case, it’s 150 pixels). The column content divs have
transparent backgrounds and are formatted to position the column text over the
corresponding background color or image.

To style the new divs, we’ll add the
following styles to the CSS stylesheet:

div#column2 {
    margin: 0;
    padding: 0;
    background-image: url(side2.gif);
    background-position: right;
    background-repeat: repeat-y;
    width: 100%;
    background-color: #FFFF99;
    
}
div#column1 {
    margin: 0px;
    padding: 0px;
    background-image: url(side1.gif);
    background-repeat: repeat-y;
    width: 100%;
    
}

To ensure that the background divs
fully enclose the floated column content, we’ll need to add a clearing element
to the code and the following style to the stylesheet. This style employs a
class selector instead of an id to
facilitate easy reuse throughout the site.

.clear {
    clear: both;
    display: block;
    height: 1px;
    overflow: hidden;
    margin: 0;
    padding: 0;
}

Here’s the XHTML markup with the
added divs:

<body>
<div id=”header”>
    <h1>Header Text</h1>
</div>
<div id=”column2″>
    <div id=”column1″>
        <div id=”navcol”>
            <h4>Nav Column</h4>
            <ul>
                <li>Let me not to the marriage of true minds</li>
                <li>Admit impediments; love is not love</li>
                <li>Which alters when it alteration finds</li>
                <li>Or bends with the remover to remove</li>
                <li>Oh, no, it is an ever fixed mark</li>
                <li>Let me not to the marriage of true minds</li>
            </ul>
        </div>
        <div id=”sidecol”>
            <h4>Starboard Side Column</h4>
            <ul>
                <li>Let me not to the marriage of true minds</li>
                <li>Admit impediments; love is not love</li>
                <li>Which alters when it alteration finds</li>
                <li>Or bends with the remover to remove</li>
            </ul>
        </div>
        <div id=”main”>
            <h2>Main Content</h2>
            <p> That looks on tempests … taken.</p>
            <p>That looks on tempests … taken.</p>
            <p>If this be error … height be taken.</p>
            <p>That looks on tempests … remove.</p>
        </div>
        <div class=”clear”>&nbsp;</div>
    </div>
</div>
<div id=”foot”>
    <p>Footer text goes here. … </p>
</div>
</body>

The result is shown in Figure C.

Deconstructing the code

There are two wrapper divs
surrounding the column content divs because we need to place background images
in two different locations. The div#column2
style creates the middle and right columns, the background-color: #FFFF99; rule defines the middle column color,
and the background image (background-image:
side2.gif;
) creates the right column. The background image is positioned to
the right side of the div (background-position:
right;
) and repeated vertically (background-repeat:
repeat-y;
). The div is floated (float:
left;
), so it follows the same positioning rules as the floated content
divs.

Similarly, the div#column1 style creates the left column with another background
image (background-image: side1.gif;).
It’s positioned on the left side of the div (background-position: left;) and repeated vertically (background-repeat: repeat-y;). There is
no background color in this div, so the background from div#column2 shows through.

The width attribute (width: 150px;) for both outer column
content divs (div#navcol and div#sidecol) exactly matches the width
of the background images for the corresponding columns. In this case, both of
the outer columns are the same width, but they could be different if that’s
what your page layout requires.

One of the secrets to this technique
is the clearing element (<div
class=”clear”>&nbsp;</div>
) that follows the main
content div. This is what pulls the background divs down to enclose the bottom
of the longest column. The clearing element is just a div containing a
nonbreaking space character. It follows the last nonfloated element in the
group of elements to be enclosed by the surrounding divs—in this case, the main
content div. The .clear class style
includes the clear: both; rule, which
forces it to flow into a position where it’s clear of floated elements on both
sides. This effectively pushes the clearing element down to the bottom of the
columns.

The background divs must expand down
the page to include the clearing element, thus ensuring that the background
colors and images extend the full height of the page columns. The rest of the .clear style attributes make sure it’s
treated as a block element and suppress its display. (Note: The height
is set to 1px rather than zero because Netscape ignores the element if its
height is 0px.)

Using this technique, you can create
a three-column layout with background colors that extend the full height of the
columns—no matter which column is longer. Figure D
and Figure E show how the page adjusts automatically to
accommodate variations in column lengths.