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

Last week’s
column
showed how to rearrange the page code in a two-column
layout to move the main text content closer to the top of the file
and move supporting elements to a less prominent position further
down in the file. This week’s article applies the same idea to a
more complicated, three-column page layout and, in the process,
demonstrates some refinements to the three-column liquid layout
technique described in my article, “Use CSS
floats to create a three-column page layout
.”

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 keeps the main content confined to a nice vertical column
instead of spreading out into the side columns. (This technique is
described in more detail in the previous column.)

The following code example builds on that basic
technique by adding a wrapper div surrounding the
divs for the three columns. The purpose of this wrapper is to
provide a background for the side columns that fills the full
height of those columns. Specifying background colors for the side
column divs in the div#navcol and div#sidecol rules would
create backgrounds only for the height of the content in each of
those columns.

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#wrapper {
    background-color: #FFFF99;
    margin: 0px;
    padding: 0px;
    width: 100%;
}
div#navcol {
    padding: 10px;
    float: left;
    width: 25%;
}
div#main {
    background-color: #99FFFF;
    padding: 10px;
    margin-left: 26%;
    margin-right: 27%;
}
div#sidecol {
    float: right;
    width: 25%;
    padding: 10px
}
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, the contents of both side column divs are shown as simple
unordered lists, and the main content and footer text is
abbreviated. The text content consists of strings of nonsense to
indicate the location of your page content.)

<body>
<div id=”header”>
    <h1>Header Text</h1>
</div>
<div id=”wrapper”>
    <div id=”navcol”>
        <h4>Nav
Column</h4>
        <ul>
            <li>Lorem
ipsum dolor</li>
            <li>Consectur
elit</li>
            <li>Sed
do eiusmod tempor</li>
            <li>Ut
labore et dolore</li>
            <li>Ut
enim ad minim</li>
        </ul>
    </div>
    <div id=”sidecol”>
        <h4>Starboard
Side Column</h4>
        <ul>
            <li>Lorem
ipsum dolor</li>
            <li>Consectur
elit</li>
            <li>Sed
do eiusmod tempor</li>
            <li>Ut
labore et dolore</li>
            <li>Ut
enim ad mini</li>
        </ul>
    </div>
    <div id=”main”>
        <h2>Main
Content</h2>
        <p>Ut
aliquip ex … consequat.</p>
        <p>Lorem
ipsum dolor … incididunt.</p>
        <p>In
reprehenderit … incididunt.</p>
        <p>Ut enim
ad minim … voluptate.</p>
    </div>
</div>
<div id=”foot”>
    <p>Footer text goes here. In
reprehenderit … laborum.</p>
</div>
</body>

The technique works, but the sequence of
elements in the page markup puts the main content following both
outer columns. We can do better!

Moving the main content up the page

Improving the sequence of the elements in the
markup for a two-column page requires little more than swapping the
position of the left and right columns. Instead of floating the nav
column to the left and allowing the main content to fill the space
to the right, it’s enough to float the main content column to the
right and allow the nav column to flow up into the empty space to
its left.

Rearranging a three-column layout is a little
more difficult. We have to work with a floated div within another
floated div. You could think of it as a two-column layout, with one
column further divided into two sub-columns to achieve the total of
three columns.

The following example code produces the effect
shown in Figure
B
. The result is essentially the same as the previous
example, but there are some significant differences in the code.
All the same divs are present but their sequence is rearranged, and
the CSS styling applies floats to different elements.

Here’s the modified CSS code:

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

And here’s the rearranged XHTML markup. Notice
that the main content now follows immediately after the header div
and the side column divs drop down to a position in the code that
is more befitting their supporting roles.

<body>
<div id=”header”>
    <h1>Header Text</h1>
</div>
<div id=”wrapper”>
    <div id=”main”>
        <h2>Main
Content</h2>
        <p>Ut
aliquip ex … consequat.</p>
        <p>Lorem
ipsum dolor … incididunt.</p>
        <p>In
reprehenderit … incididunt.</p>
        <p>Ut enim
ad minim … voluptate.</p>
    </div>
    <div id=”navcol”>
        <h4>Nav
Column</h4>
        <ul>
            <li>Lorem
ipsum dolor</li>
            <li>Consectur
elit</li>
            <li>Sed
do eiusmod tempor</li>
            <li>Ut
labore et dolore</li>
            <li>Ut
enim ad minim</li>
        </ul>
    </div>
</div>
<div id=”sidecol”>
    <h4>Starboard Side
Column</h4>
    <ul>
        <li>Lorem
ipsum dolor</li>
        <li>Consectur
elit</li>
        <li>Sed do
eiusmod tempor</li>
        <li>Ut
labore et dolore</li>
        <li>Ut enim
ad mini</li>
    </ul>
</div>
<div id=”foot”>
    <p>Footer text goes here. In
reprehenderit … laborum.</p>
</div>
</body>

Here’s how it works

The wrapper div creates a container for two of
the three columns–in this case, the main column and the nav
column. The div#wrapper
style floats that div to the left and sets its width to 75
percent.

Within the wrapper div, the main content div
floats right. The div#main style specifies the
float and also sets the width of that column to 66 percent. The
float and width of the main div are both relative to the wrapper
div, not the whole page. Therefore, the main div occupies the
right-hand two-thirds of the wrapper div. Since the wrapper div is
floated left, that puts the main div in the center of the
window.

The navcol div is also contained within the
wrapper div and its contents flow up into the blank space to the
left of the main div. The div#navcol style no longer
includes a float.

Since the wrapper div is floated and doesn’t
fill the full width of the window, the remaining div (sidecol) has
room to flow up into the space to the right of the wrapper div,
forming the third column. The div#sidecol style no longer
includes a float, but it does set the left margin equal to the
width of the wrapper div to keep the right column from encroaching
on the other columns.

Tips

Note that the div#navcol style doesn’t
include a background color–the nav column gets its background from
the wrapper div. This enables the background color to fill the full
height of the column instead of just the height of the div
content.

The div#sidecol style doesn’t
include a background color either. The right side column gets its
background from the main page background. Because of the way floats
work, an unfloated element that follows a float flows up to fill
any unoccupied space left by the floated element. Text is confined
by the edges of the floated element, but the background color of an
unfloated element can flow behind the floated element text and fill
any unoccupied space left by another element. As a result, defining
a background color in the div#sidecol style would
extend that color into the blank space below the navcol div.

Because of the way the floats and background
colors work, this code gives the desired results only when the main
content div is the tallest of the three columns. There are ways to
compensate for columns of unpredictably differing heights, but
that’s the subject of another article. In many cases, the main
content is predictably the longest column and this technique will
work without adding further complications.