Solution to multi-column page layout problems

Example multi-column page layout
Script for multi-column example
Cheat sheet

Multi-column layout screen-grab image

Ever since CSS and the box-model turned up, it has been practical to break a web page into areas of content which can be individually positioned and styled without resorting to the clumsiness of tables. The fly in the ointment is that there can be more to floating objects around on the page than you at first imagine and can end up with each block of content wrapping itself around the next in unexpected or undesirable ways. This is especially true of multi-column layouts and can require a good bit of tweaking to eradicate these effects. This article demonstrates a simple, robust and trouble-free, multi-column layout solution that will always work.

How it works

There is a cheat sheet at the bottom of this page for those in a hurry. Have a look at the example multi-column page layout to see the layout this technique creates. Here is the (printer friendly) script used to create the example page, which you are welcome to copy and paste. Let's break it up and find out how it works and how you can reuse this technique over and over.

    /* set the usable page area */
div#pagearea { margin: 0 auto; max-width: 1100px; } /* control column alignments */ div#left, div#main, div#right { float: left; margin: 0; padding: 0; min-height: 10em; }

The usable area of the page has been defined in a container called pagearea. The maximum width of the usable page has been set to 1100 pixels. This allows it to shrink if there is a narrower page window. It is centred in the browser window using the margin property to set the top and bottom margins to 0 and the left and right margins to auto.

Now let's focus on the styling that I've labelled 'control column alignments'. The page in the example is going to have three columns called left, main and right. These are all set to float: left so that they line up next to each other. Further more, I have made sure that they have 0 margin and padding. Most browsers nowadays do this as standard, but set this anyway to make sure that your nice page layout is not messed up by non-conforming browsers.

A minimum height has also been assigned to these columns. This ensures that, if you leave a column empty, it will still take up it's assigned width and the page will paginate as you expected.

Next some widths are assigned to the column containers. This is best done as percentages using a % value, which makes the page layout more pliant and allows your page to be responsive to the screen size that it is vewed on.

    /* set the relative column widths */
    div#header		{ width: 100%; }
    div#left 		{ width: 25%; }
    div#main 		{ width: 55%; } 
    div#right 		{ width: 20%; }
    div#footer		{ clear: both; }

The total of the column widths adds up to 100% so that they will all fit alongside each other and will together take up the full width of the defined page area. At the same time, a header container has been defined which is 100% of the width of the page. This will act as a banner across the entire top of the page. A footer is also defined. Because the containers preceding it are floated, it is possible that it will not behave as we want even if it is assigned a width of 100%. Instead I force it to take up residence below the columns by setting clear: both. This ensures that no other content can exist left or right of it.

Now we are nearly ready to start creating the page. It is worth creating a class for article container boxes. In the example this class is called articlebox. These containers can be used to provide your content with the borders, margins and padding that the column containers lack. I have wrapped one of these around each article and placed my headlines, images text and any other content I may need inside one of these.

Below are the key styling properties used in this example -

    /* set styling for the multi-column layout */

    body { 
        background-color: Ivory; 
        font-family: 'Times New Roman', Georgia, Serif; 
    }
    div#pagearea { 
        background-color: white; 
    }
    div.articlebox { 
        padding: 0 0.5em 0.5em 0.5em; 
        margin: 0 0.5em 0.5em 0.5em; 
        border: 2px solid Lavender; 
    }

All that is left to do is to create some content styling before getting down to the business of the content itself.

Have another look at how the contents have been organised into the containers that we have created. A <div> for the header contains nothing more than a short bit of text and a headline. Each column contains a content box for each article and these are used to contain any headlines, text and other content for the article. The middle column contains an image which is floated to the left in order to allow the text to flow around it. The footer at the bottom of the page has a single line of text and a link.

That pretty much wraps up this solution. By the way, it's good practice to include a footer as some odd side effects can occur if you choose to leave it out. In this example the overall background of the browser window has been set to ivory while the working page area has had it's background set to white. Without a footer to 'pin' the white background in place, it will disappear. This is due to the intricacies of how the z-index context instances are maintained and goes beyond the scope of this article.

▲ top

Summary cheat sheet

You can cut and paste this solution and take it as read that it works. But here is what you need to know in order that this solution works robustly -

  • Each column should have it's own <div> container. Be aware that the width you define for each column is the width of that column's content only, which does not include padding, borders, margins or ouline. Avoid defining any margins and padding etc for these outer column containers as it will become difficult to maintain overall control of the width, so the columns will end up not fitting gracefully side by side on the page.
  • Each column should have it's width set as a percentage of the usable page and should be floated left. The total percent of the columns should add up to a number no greater than 100.
  • Each content article in the column containers should be contained in its own article box. Styling attributes such as padding, margins, borders and outline that the column containers themselves lack, can be added here.
  • A footer element should be placed at the bottom of the page even if you do not need to use it. You can always leave it empty. It should be set clear of other floating elements on both sides with 'clear: both'. This will resolve several HTML layout issues that go beyond the scope of this article.

This example can be modified endlessly and will always produce reliable multi-column pages on your websites.