Two-Column Layout
How to create a tableless, two-column visual layout for a web page, using basic XHTML and CSS.
Contents |
Design Goals
- The design should be capable of being adapted to being fluid (expands/contracts with the window) or fixed (always the same width).
- There should be a header, followed by two columns for main content and a sidebar.
- There should be a footer at the bottom that is always beneath the longest column.
- The content should appear before the sidebar in the code.
- The column widths should be easy to adjust.
- It should be easy to swap the position of the columns.
- The design should work on as many browsers as possible.
Visual Layout
Basic XHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Two-Column Layout</title>
</head>
<body>
<div id="wrap">
<div id="header">
...header content goes here
</div>
<div id="content">
...main content goes here
</div>
<div id="sidebar">
...sidebar content goes here
</div>
<div id="footer">
...footer content goes here
</div>
</div>
</body>
</html>
Basic CSS
#wrap {
width: 750px; /* remove for fluid layout */
}
#content {
width: 65%;
float: left;
}
#sidebar {
width: 35%;
float: right;
}
#footer {
clear: both;
}
Note: Some browsers have rounding errors when dealing with percentages. It may be necessary to tweak the width of either the content or the sidebar div elements to open up a percentage point or two between them.
Enhancements
Gutters
As is stands, the layout will have no guttering between columns. Adding some padding to the DIV elements would achieve this; however, differences in web browser interpretations of CSS require additional markup to ensure the layout doesn't "break". Add a child DIV element to the columns:
<div id="content">
<div>
...main content goes here
</div>
</div><!-- content -->
Padding can now be applied to the new child:
#content div {
padding: 20px;
}
False Columns
Using CSS, it is difficult to get a background color on the shortest column to extend all the way down to the footer. It is therefore necessary to create false columns by vertically tiling a background image on the parent "wrap" DIV element. In the example above, there is a 65/35 percent split between the main content column and the sidebar column. In order to make the false column work in both a fluid and a fixed layout, the background must be offset to the right by the same percentage (65).
Create a background image that is wide enough to cope with all browser combinations, say 3000 pixels. It needs to be no more than 1 pixel high, but it might be easier to work with the image file if it was higher. If the content is to be on the left, give the right 35% a different background color from the left (from the 1950th pixel upwards).
Using CSS, vertically tile the image as a background for the DIV with an ID of wrap:
#wrap {
width: 750px; /* remove for fluid layout */
background: url(false_cols.png) repeat-y 65% 0;
}
Even in a fluid layout, the dividing line between the two columns will remain fixed in place when the browser window is resized.

