Faux Columns

This past week has been really crazy: 3 Christmas celebrations, 1 Birthday, and family staying over for the last 3 days. Consequently, I have not succeeded in a finishing my xJson Object article. So instead of discussing xJson, today we will discuss a simpler, but very useful technique, known as Faux Columns.

The Problem:

If you have ever tried to design a two-column layout without using tables, you should know that the two columns (by default) will not be the same height. This is normally not a problem until you want a line of some kind dividing the columns. This line should be the height of the tallest column. Initially, you might think that adding a border-right to the left column or a border-left to the right column, will do the trick. However, because one column may (and probably will) be larger than the other, borders will not work. The simplest fix is to apply a height to both columns and call it a day. However, many layouts have dynamic content, such as this blog, and you will not be able to specify a height.

The Solution:

There are many different solutions to this problem (including JavaScript, CSS hacks, etc.), but the simplest (and x-browser safest) one is Faux Columns; it requires no hacks, only good HTML and CSS design. Faux Columns were first introduce by A List Apart. Since, the column height can be dynamic, instead of applying a background or border to the columns, you wrap the columns inside an element and apply a background style to that element. That background style will have your column background and border styles. For example, lets assume you use the following HTML:

Example 1: Simple HTML

Put content elements here

And you want to use this HTML to produce a two column layout with a column-independent header and footer:

Example 2: Layout

faux layout example

Then apply the following styles (I recommend using reset.css and base.css as well):

Example 3: Styles

/** Center the doc div; excluding IE, see IEHacks for more info on how to do this in IE < 6 */
#doc {
	margin: 0.5em auto;
	overflow: hidden;
	width: 90em;
}

/** Replace these with whatever styles you prefer */
#header {
	border-bottom: 1px solid #830A04;
	height: 3.6em;
}

/** Creates the faux column */
#main {
	background: #EFEFEF url(../images/bg/column.gif) 25em 10px repeat-y; /** faux column graphic */
	clear: both;
}

/** Right column */
#content {
	float: right;
	width: 64em;
}

/** Left column */
#sidebar {
	float: left;
	width: 24em;
}

/** Replace these with whatever styles you prefer */
#footer {
	background-color: #FFF;
	border-top: solid 1px #000;
	clear: both;
	padding-top: 1em;
}

/* (en) clearfix method for clearing floats */
.clearfix:after {
	content: ".";
	display: block;
	height: 0;
	clear: both;
	visibility: hidden;
}

/* (en) essential for Safari browser !! */
.clearfix {
	display: block;
}

I prefer my designs to be 100% elastic so that they are accessible and have used ems to specific widths. However, you could just as easily use pixels and a fixed layout. If you use the reset.css and base.css then 1em = 10pixels. In this example, the background image is a solid color with the column divider graphic on the left side, and the sidebar color is specified by the background style of main. This way, I simply offset the background image to the width of the sidebar, and it scales to all font-sizes. The only constraint on the background image is that it needs to repeat vertically, otherwise, you will not get the column effect (so you need to create a repeating vertical pattern).

If you use a fixed layout and want a less plain sidebar design, then do not offset the image. Instead offset the column divider in your graphic to the width of the sidebar (or wherever you need the gutter).

You might be wondering why the empty div with class clearfix is there. This is needed because the main divs height will not reflect the height of the content floating inside it. The clearfix div forces an empty div to be placed at the end of the columns that clears both the left and right float. This non-floating element, is positioned after the tallest floating content and causes the main&rsquot; div to then expand to the height of the largest column.

Here is a simple example that uses a double vertical line to divide the columns.