Simple 2 column CSS layout

This is a tutorial on how to use CSS to create a simple two column layout. If you want to create a three column layout, read on as this tutorial explains a basic concept that can be used to create as many columns as you need.

The layout consists of a header, a horizontal navigation bar, a main content column, a sidebar, and a footer. It is also horizontally centered in the browser window. A pretty basic layout, and not at all difficult to create with CSS once you know how to deal with the inevitable Internet Explorer bugs.

To see the full CSS used for each step, view source on the example documents.

1. Basic structure

First of all, we create the basic HTML structure:

  1. <div id="wrap">
  2. <div id="header"></div>
  3. <div id="nav"></div>
  4. <div id="main"></div>
  5. <div id="sidebar"></div>
  6. <div id="footer"></div>
  7. </div>

After that, we put some content in the different sections:

  1. <div id="wrap">
  2. <div id="header"><h1>Document Heading</h1></div>
  3. <div id="nav">
  4. <ul>
  5. <li><a href="#">Option 1</a></li>
  6. <li><a href="#">Option 2</a></li>
  7. ...
  8. </ul>
  9. </div>
  10. <div id="main">
  11. <h2>Column 1</h2>
  12. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit...</p>
  13. </div>
  14. <div id="sidebar">
  15. <h2>Column 2</h2>
  16. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit...</p>
  17. <ul>
  18. <li><a href="#">Link 1</a></li>
  19. <li><a href="#">Link 2</a></li>
  20. ...
  21. </ul>
  22. </div>
  23. <div id="footer">
  24. <p>Footer</p>
  25. </div>
  26. </div>

Now we have a completely unstyled HTML document which is structured in a way that lets us use CSS to control its layout.

View step 1.

2. Adjust the body and html elements

To make the content reach the edges of the browser window, we set the margin and padding of the body and html elements to zero. We also specify colours for text and background.

  1. body,
  2. html {
  3. margin:0;
  4. padding:0;
  5. color:#000;
  6. background:#a7a09a;
  7. }

View step 2.

3. On to the main containers

After that it’s time to give the content area a width and center it horizontally. We do that by specifying the width and margins of the main container, #wrap. We also give it a background colour to make it show up on the page.

The method we use to center the content is based on the fact that when an element’s left and right margins are set to auto, they will share whatever is left when the element’s width has been subtracted from that of its container. In this case the width of #wrap will be subtracted from the width of the browser window.

Note: for this method to work in Internet Explorer (version 6 and later only), the document must use a DOCTYPE that forces IE to use its standards mode. Please read Fix Your Site With the Right DOCTYPE! for more info.

  1. #wrap {
  2. width:750px;
  3. margin:0 auto;
  4. background:#99c;
  5. }

In case you’re wondering why we’re not using the body element to control the width and centering of the layout, it is because doing so can cause unwanted side-effects in some versions of Internet Explorer.

After that, we give the different sections of the document different background colours to make them show up.

  1. #header {
  2. background:#ddd;
  3. }
  4. #nav {
  5. background:#c99;
  6. }
  7. #main {
  8. background:#9c9;
  9. }
  10. #sidebar {
  11. background:#c9c;
  12. }
  13. #footer {
  14. background:#cc9;
  15. }

View step 3.

4. Place the columns side by side

To make the two columns (#main and #sidebar) display side by side we float them, one to the left and the other to the right. We also specify the widths of the columns.

  1. #main {
  2. float:left;
  3. width:500px;
  4. background:#9c9;
  5. }
  6. #sidebar {
  7. float:right;
  8. width:250px;
  9. background:#c9c;
  10. }

Note that the sum of the widths should be equal to the width given to #wrap in Step 3.

This will make #sidebar appear to the right of #main, but the footer is not where it should be.

View step 4.

5. Push the footer down

The footer doesn’t get pushed down to the bottom of the content because of the way float works. When you float an element, it is removed from the document flow and doesn’t push elements that follow it down. In this case #footer will start right below #sidebar.

To avoid this we use the clear property to tell the footer that it can’t have any elements next to it.

  1. #footer {
  2. clear:both;
  3. background:#cc9;
  4. }

View step 5.

6. Fix the background colour

Now we can see that the shorter column doesn’t continue all the way down to the footer. To make it look like it does, we use the same background colour for #sidebar and #wrap.

  1. #sidebar {
  2. float:right;
  3. width:250px;
  4. background:#99c;
  5. }

Also, if you take a look at this step in Internet Explorer 6 you may notice that the background colour of the footer is pushing up beside the main content. That will be taken care of later.

View step 6.

If you don't know which column is going to be the tallest, and you want both columns to have different backgrounds and look like they are going all the way to the bottom, you need to use a workaround. There are several ways to achieve that effect:

7. Make the navigation bar horizontal

#nav contains a regular unordered list of links. Since we don’t want it to look like an unordered list we restyle it.

  1. #nav ul {
  2. margin:0;
  3. padding:0;
  4. list-style:none;
  5. }
  6. #nav li {
  7. display:inline;
  8. margin:0;
  9. padding:0;
  10. }

View step 7.

8. Adjust margins and paddings, and make IE 6 cooperate

Almost done. Time to adjust the margin and padding of some elements to make the layout a little less cramped.

  1. #header {
  2. padding:5px 10px;
  3. background:#ddd;
  4. }
  5. h1 {
  6. margin:0;
  7. }
  8. #nav {
  9. padding:5px 10px;
  10. background:#c99;
  11. }
  12. #main {
  13. float:left;
  14. width:480px;
  15. padding:10px;
  16. background:#9c9;
  17. }
  18. h2 {
  19. margin:0 0 1em;
  20. }
  21. #sidebar {
  22. float:right;
  23. width:230px;
  24. padding:10px;
  25. background:#99c;
  26. }
  27. #footer {
  28. clear:both;
  29. padding:5px 10px;
  30. background:#cc9;
  31. }
  32. #footer p {
  33. margin:0;
  34. }

One thing to take note of here is that when we added padding to #main and #sidebar, we subtracted the width of the left and right paddings from each element’s width. This is how the CSS box model works – for more details on that, see Internet Explorer and the CSS box model.

And the final thing is to compensate for a float bug in Internet Explorer 6. If you look at step 6 in IE 6, you’ll notice that the footer is not always being pushed completely below #main. Scroll up and down a couple of times if you can’t see it immediately.

It is very noticeable in this demo because every major element has a different background colour and everything is really tight. One way of fixing this problem is making sure the footer has an Internet Explorer concept called Layout. There are several ways of achieving this, but we’ll do it by using the Star HTML CSS hack to give the footer a height only in IE 6:

  1. * html #footer {
  2. height:1px;
  3. }

As strange as it may look, this does the job. Thanks to another bug in IE, the footer will not be just one pixel tall, but as tall as its content dictates.

And we’re done. We have created a simple layout that can be used as a starter for more advanced layouts.

View the final layout.

Please don’t hesitate to contact me if you can suggest improvements to this method.