Developer

Raise text relevance by rearranging a three-column layout

Michael Meadhra demonstrates how to build on the basic technique for creating a three-column liquid layout by adding a wrapper div surrounding the divs for the three columns.

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.

Editor's Picks

Free Newsletters, In your Inbox