Use the links below to share Pushing the Limits (Part 1): The Perfectly Semantic Three Column CSS Layout on your favorite social networks.

Back to the Article >>

Pushing the Limits (Part 1): The Perfectly Semantic Three Column CSS Layout

July 7th, 2008 in Design Tips & Tutorials

by: Matthew Griffin

Building a three or four column layout on the web without the help of a table can be a difficult task. The CSS3 spec proposes a perfectly tailored solution; but, unfortunately, CSS3 support is spotty at best even in modern browsers. We're stuck with CSS2 until that changes, so we might as well make the best of it. There are a number of ways to overcome the lack of multi-column support in CSS and none of them is very pretty.  The three-column layout is the easiest to achieve without stepping outside the semantic boundaries, so we'll start there. Then in the next few articles we'll move on to the rarely explored waters of four-column+ CSS layouts.

The Problem with the Three-Column Layout

The problem we run into when attempting to build a semantically correct three column layout is that CSS only provides two attribute values for positioning relatively positioned block-level elements horizontally. Those two attribute values are, of course: float: right and float: left. To build a two column layout, then, all you have to do is create two <div> tag pairs and float one right and the other left. Viola, a two column layout.

Try to take a step up to the three-column layout, though, and you will quickly find that there is no such thing as float: center. But take heart—there is a semantically correct solution that will get the job done. No need to run back to <table> tags or, worse yet, a semantically incorrect usage of unordered lists.

Getting Your XHTML markup ready

We'll start our example with a snippet of semantically correct XHTML (it will validate as HTML 4.01 as well) markup for our content. The end product will be a fixed-width three column layout and you can see it/steal it here. Our markup will include a header, three <div>s for content , and a footer <div>. Here's how it looks:

<div id="wrapper">

    <h1>My Personal Homepage</h1>

    <div id="navigation">
        Navigation
    </div>

    <div id="sidebar">
        Sidebar
    </div>

    <div id="content">
        Content
    </div>

    <div id="footer">
        Thanks for stopping by my personal home page! Come back soon!
    </div>

</div>

Just as a side note: notice that each of the three-columns is given an id that describes the type of content it holds, rather than its position on the screen. This type of identification makes it easy to navigate the markup and easy to alter the layout in the future without turning your ids into nonsense. For example, if you named your navigation column "leftcolumn" and in the future you wanted the navigation to be on the right; you could easily make the change in your stylesheet, but the id would no longer make sense. If you want to take it a step further, you can label the columns even more generic names like "sidebar1" and "sidebar2"; but I find that it's rare that the content in a navigation <div> changes to something non-navigation.

Using CSS to Style Your Columns into Submission

Now that we have a nice, light-weight page marked up, we'll add some CSS to horizontally align our columns. The final product we are shooting for is a centered, fixed-width, three-column layout; so we'll start by setting a reasonable width for the "container" <div> and centering it. Next, we're going to set the widths of our two sidebar columns (called "sidebar" and "navigation") and float one to the left and one to the right. When we're finished, the "content" <div> will slide right up between our two sidebars to form the middle column in our three-column layout. Here's what the CSS looks like:

body {
    font: 1em Verdana, Arial, Helvetica, sans-serif;
    background: #ccc;
    color: #000;
    text-align: center; /* Centers the container */
    margin: 0;
    padding: 0;
}

#wrapper {
    width: 780px; /* 780px is just wide enough to fill and 800px screen */
    margin: 0 auto; /* It's important to set the margin to auto if you want the layout to center */
    background: #fff;
    text-align: left;
    border: 1px solid #999;
}

#header, #sidebar, #navigation, #footer, #content {
    padding: 10px;  /* This sets a 10px padding on all of our content boxes */
}

#header {
    background: #999;
    margin: 0;
    padding 0;
}

#sidebar {
    float: left; /* Sets this column to the left */
    background: #ccc;
    width: 160px;
}

#navigation {
    float: right; /*Sets this column to the right */
    background: #ccc;
    width: 160px;
}

#content {
    margin: 0 190px; /* Sets the margin to 190px on the right and left */
}

#footer {
    background: #999;
    clear: both;
}

Again, a full working example is available here if you want to see it in action. The CSS is in the <header> of the file to make it easier to read. This first solution to the 3+ column CSS layout issue is by far the easiest and most semantic solution available. Unfortunately, when you get past three columns, it starts to get a little stinkier. Next week, we'll look at one four-column CSS layout technique.

Some Final Notes

The example is free for copying but there are a few things I should point out before you run with it. First, in my markup, I didn't put <p> tags or any other semantic tags around the content that appears in the various content boxes. I did this so we could focus on the layout; but in reality, you should put semantically correct tags around all of your content.

Also, the example will work perfectly in all modern standards-compliant browsers and IE at least as far back as version 5.5. However, I specifically avoided markup that would be susceptible to IE box model bugs that appeared pre IE7. Just be warned that if you mess with the padding and markup very much, the layout may break in IE6 and earlier.

  • 18 Comments
  • 14805 Views

Back to the Article >>