This site will look much better in a browser that supports web standards, but it is accessible to any browser or Internet device.


Skidoo : 2 or 3 Column Layout



Don't bother with the large number of CSS files this layout uses. Feel free to compress them into one or two stylesheets. Excessive stylesheets can lead to a huge increase in the size of your webserver's logs. Every page hit means 8 CSS files need to also be accessed. That's a total of 9 requests per page load. Be nice to your webserver.



The Goal

A layout with 2 or 3 columns that does not rely on tables to create the layout structure. This layout must support a header and a footer which carry the width of the page and the footer must be located below the document's content. The background colors of each column must be derived from CSS and not rely on any background images. The center column must be capable of being fluid if so desired.

Devil in the Details

Getting three columns to line up next to each other, using just CSS, is a (fairly) simple matter of setting the float property on each column. To place a footer below the three columns, regardless of which one was taller, just set the clear property on that footer element and it will appear below the three (floating) columns.

We start to get into problems when we want each of the three columns to carry the full height of the page regardless of which one is taller. For various reasons, height:100%; won't do what you might think it should. We can't use that approach. In fact we can't use any approach, short of using some CSS enhancer such as JavaScript. CSS alone just won't do it. The solution: fake it. While the column itself won't go as tall as the document, there are ways to make it appear (visually) that the column carries the full height.

A very handy, and popular, trick to make columns appear equal height regardless of which one is taller is to use a container element in which the columns sit. We can then apply a background color to that container element which will act as the background color for one column. Then use a background image, the same width as one of the columns and repeated vertically only, to act as the background for a second column. Since the container element will contain all three columns, we know it will be the same height of whatever the tallest column is. So the background color, and that vertically-repeating image, will carry the full height of the document. You can see a two-column example of this approach here. Handling the third column would be a simple matter of adding a second container element or using an image to create the background for at least 2 of the 3 columns.

However, what if we don't want to use images? What if we want everything CSS-driven, including the background colors for each column. We can't use the background-color property for those three floating columns because those colors will only carry the height of the column's content, not the full page. A previous attempt I made at this required heavy hacking to create a color mask layer that appeared below the content layer. It somewhat worked, but was way too complicated, required way to many hacks, and far too much markup, to be practical. So what else is there?

The Trick

The solution used in this layout was first developed (as far as I am aware of) by Douglas Livingstone. His approach was to use negative margins on the side columns to move them (almost) outside of their container element. This allows a grandparent element (a parent to the columns' container element) to take responsibility for generating the background of those two side columns. The background of the middle column becomes the responsibility of the three columns' parent container.

So how does the grandparent container create the background colors for the side columns? Borders. We define left and right borders on the grandparent element that have the same width as the left and right columns. The negative margins then allow the left and right columns to move (almost) outside of their parent container and onto the borders being generated by the grandparent element.

The relevant markup takes on the following structure:

  • Grandparent Container
    • Parent Container
      • Left Column
      • Middle Column
      • Right Column
      • clearing element

The clearing element is important. By placing it inside the parent container, it forces the parent container to contain (visually) all three columns regardless of which one is taller. Because of this clearing element we can be certain that the parent container will be as tall as the tallest column, thus, the grandparent container will also be as tall, thus the borders of that grandparent element (acting as the side columns' background colors) will carry the full height of the content.

Not So Fast

There's still one problem. If the side columns have enough of a negative margin to move them completely outside the parent container's dimensions, then the clearing element inside the parent container won't operate on those two side columns. So how can we move the columns out of the parent container, but yet keep them in it?

A 1px margin is applied to the opposite side of the negative margins on these side columns. This allows them to still peek into the parent column and the effect of the clearing element works as we want it to. We also need a -1px margin on the sides of the parent container so the parent container also acts to overlap the side columns. With this 1/2 punch of 1px margins, the effect is complete. The clearing element will force the parent container to take the height of the tallest of the three columns, and thus the grandparent container will as well. With the 2 borders of the grandparent container and the background color of the parent container taking the full height of the content, we can use these three pieces of the layout to generate faux background-colors for each column.

Happy Side Effects

All three columns are floats. This means that several IE-related bugs disappear because there's no non-floated element for the floats to act upon. This approach also requires virtually no CSS hacks to get it working in version 5 and better browsers. Many previous approaches to this layout required heavy use of CSS hacks. This is a very good step in the right direction.

Unhappy Side Effects

IE6/Win seems to have a problem with elements that take up no visual space on the page, such as comments and elements with the display property set to none. The result is that duplicate characters start to appear in your layout.

Luckily, the fix for this isn't difficult. The bug is triggered only when these empty/hidden elements are placed in-between floating elements that appear side-by-side. So by taking care not to place any comments or elements with display set to none in-between the three floating columns will keep this bug away. If you start to experience this bug, start looking at your markup, look for any comments or elements that come between floated blocks. That's where your problem will be.

Compatibility

Target compatibility for this layout is version 5 (or equivalent) browsers and later. These browsers should render the page correctly. Version 4 and earlier and non-CSS capable browsers will just see a flat file, making your use of markup to help convey meaning very important. Don't just rely on CSS to make an object bold, or to underline a piece of text. Use HTML elements to do some of this for you. It allows these older browsers to still render at least some of the meaning you want to convey with such effects.

The v4.css stylesheet is available to provide enough CSS to render a three-column layout in NN4 and IE4. It does not even come close to rendering this page, as it appears in version 5 browsers, in version 4 browsers. In fact, under IE4 it's especially ugly. It is here for those people who wish or require it, but if you don't need it, it's not recommended.

Two Columns

It's very simple to change this into a two-column layout, regardless of which side you want the narrower column to appear on. All you need to do is include one extra stylesheet which overrides the CSS needed to create the column you want to remove.

For the narrow column to be on the left, simple include twoColumnsLeft.css. To place the narrow column on the right, instead you would include twoColumnsRight.css

Feedback & Usage

I welcome any and all comments, especially if you've found the layout useful and are now using it for a website. I'd like to start a list of sites that use this layout and publish it on this site so other visitors can see what people are doing with the layout. If you'd be willing to offer up your site on such a list, or have any comments you'd like to offer, you can contact me via e-mail at ruthsarian@gmail.com. Thanks.

i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i