The search for a technique that offers real equal height columns leads nowhere because we don't have full vertical control in current CSS 2.1 implementations cross browser
This is how Ingo Chao start his article presenting a method to create a css-based layout with equal height columns. Having columns with equal heights is not something always easy to do if you only rely on CSS, and beside the Faux column method, I'm not aware of any stable way to create equal height columns using only CSS without any extra markup.
After some more research on the subject, the solutions I found were either buggy or complicated to implement, so I decided to experiment with all these methods to create a simple and flexible method, that would load the content before the sidebars, that could be either fluid, fixed or grid-like, and of course, work across all browsers.
I have to admit that I REALLY thought that I was inventing something, until I found this article from Paul O'Brien. His method uses the same positionning trick as the one I use for the columns.. My only real contribution would be to make a fusion of a holy-grail-like method with the O'Brien method. The final layout can be modified very easily, switched from fluid to fixed or grid-like on demand, loads the content before the sidebars (content->left->right), can be adapted to as many columns as you want, works on pretty much all browsers, and of course, simulate equal heights columns.
Quickly explained
Like the O'brien method, I use an extra <div> (I know, shame on me!) for each column. Then I position them absolutely and this is where the real magic is happening. A normal block with a height of 100% can only fill its container if the container itself have a height. But this doesn't apply if the block is positioned absolutely. So if I position the block to the bottom and give it a height of 100%, it creates a background for the column that will extend until the footer of the page. Do this for each column, and you end up with a layout with equal height column.
Here are some examples of the final layouts, and some HTML slides that present the method step by step.
The concept step by step

- You start with a normal layout.

- We won't be using the 'real' columns to have a background.

- Instead, we add three
<div>at the bottom of the page, that have the same class as their respective columns, so the<div>are aligned with their columns. 
- The
<div>are positioned absolute. 
- Give each
<div>aheightof 100%, and positioning to the bottom creates the full-height columns. 
- Bring the content back up with
z-index:2;and voilà !
A closer look at the code
here is the original markup I use. It could be a little bit lighter if you consider that IE is not worth worrying about, as #main is only used to fix a clearing issue.
<div id="page">
<div id="header">...</div>
<div id="main">
<div id="content">
<div id="content-inner" class="column center">...</div>
</div>
<div id="left" class="column left">...</div>
<div id="right" class="column right">...</div>
</div> <!-- /main -->
<div id="footer">...</div>
</div><!-- /page -->
Here is a graphical representation of the <div>:

The base Layout
Let's have a closer look at how the layout is created. First of all, I always start with a simple browser reset.
*{
margin:0;
padding:0;
}
Then we can start setting up the layout. We add some colors to see what we're doing:
#header, #footer{background-color: #ccc;}
#left{background-color:#d7ecff;}
#right{background-color:#daffc6;}
#content-inner{background-color:#fff2d7;}
Setting up the width of the sidebars.
.left {
width: 220px;
}
.right{
width: 150px;
}
Then prepare the content to compensate for the sidebars once they are positioned correctly.
#content-inner {
margin-left: 220px;
margin-right: 150px;
}
Bringing the sidebars back at the same level of the content, using the #content and by floating all columns.
#content {
float:left;
width:100%;
margin-right:-100%;
}
.column {
float:left;
}
A quick insurance for IE to work properly... un-floating the center column.
#content-inner {
float:none;
margin-left: 220px;
margin-right: 150px;
}
The right sidebar shouldn't be floating left, but right.
.right{
float:right;
width: 150px;
}
Last touch, the footer should clear the columns. Plus some styles.
#footer, #header{
clear:both;
text-align:center;
font-size:2em;
}
The layout is done, so you should have something like this. So far so good, it works across all browsers without any hacking. But you'll notice that all the column have a different height, and this is what we are now going to fix.
The Equal Height Columns
Firts, let's add the empty <div> (blush). Notice how we give the same class right, left or center to the empty <div> so they behave like their corresponding columns.
<div id="page">
<div id="header">...</div>
<div id="main">
<div id="content">
<div id="content-inner" class="column center">...</div>
</div>
<div id="left" class="column left">...</div>
<div id="right" class="column right">...</div>
</div> <!-- /main -->
<!-- These are used to create the columns background -->
<div id="bgcenter" class="bg center"></div>
<div id="bgleft" class="bg left"></div>
<div id="bgright" class="bg right"></div>
<div id="footer">...</div>
</div><!-- /page -->
As these <div> are empty, you shouldn't notice any difference in your layout. In order to see our work, we are going to change the color rules to be applied on these empty <div>.
#bgleft{background-color:#d7ecff;}
#bgright{background-color:#daffc6;}
#bgcenter{background-color:#fff2d7;}
Now that we have the colors applied on the futur 'fake columns', let's start the magic. First, as we are going to position the fake columns, and reset their relative element to the #page element.
#page{
position:relative;
}
Now we can position the fake columns and give them a height. It is very important to position these at the bottom, for browser compatibility.
.bg{
position:absolute;
bottom:0;
height:100%;
}
Then we can override these general rules for each column to position them correctly and with the right width.
#bgleft{
left:0;
}
#bgright{
right:0;
}
#bgcenter{
right:0;
width:100%;
}
Notice how we can give a width of 100% to the content as it's loaded before the other columns, so it'll show up under them. Now everything is fine, but the fake columns are showing up on top of the content... not good, so in order to bring the content back up, I just need to play with it's z-index of the content:
#content, #left, #right, #header, #footer{
position:relative;
z-index:2;
}
There you go! All columns appear to be the exact same height, and you can even style each one of them independently. But of course, as I said a little bit earlier, all versions of IE before version 8 need a little bit of tweaking. Nothing serious though... drop this in your <head> and it should fix it all !
<!--[if lt IE 8]>
<style type="text/css">
/* Only Hack for IE */
#main, #page{ height:1%; }
.bg{ height:1000em; }
</style>
<![endif]-->
I prepared some examples of this method, with fluid or fixed width, and even with a "fluid grid example". Except for the extra markup, the only drawback that I could think about this method is that the header and footer needs to be hiding the columns. It might be ok for simple projects, but maybe a little bit tricky for more complex layouts.
I also worked on integrating this method with a full height layout, so the footer remains at the bottom of the view port if the page isn't long enough. The result is fairly stable, except for Opera... still need some work, it's getting very close to a full-featured and flexible layout, only using CSS.
References
- A List Apart: Faux Columns
- http://alistapart.com/articles/fauxcolumns/
- A List Apart: In Search of the Holy Grail
- http://www.alistapart.com/articles/holygrail
- A List Apart: Creating Liquid Layouts with Negative Margins
- http://alistapart.com/articles/negativemargins
- Ingo Chao: Companion column method
- http://www.satzansatz.de/cssd/companions.html
- CSS layout: 100% height with header and footer
- http://www.xs4all.nl/~peterned/examples/csslayout1.html
- How to Make Equal Columns in CSS
- http://www.search-this.com/2007/02/26/how-to-make-equal-columns-in-css/
- Position is Everything: In search of the One True Layout
- http://www.positioniseverything.net/articles/onetruelayout/
This is not wordpress, it's
This is not wordpress, it's Drupal, and yes, I did it myself :)
Very nicely done. Now, how
Very nicely done.
Now, how do I add border to these, say 2-column, layout with margin to separate them?
What about using css on the
What about using css on the fake columns ?
You can style the columns using css the same way you can style any element of the page.
something like this :
border-right:1px solid #ccc;
}
Makes sense ?
Fabulous!!! In the .css, is a
Fabulous!!! In the .css, is a .center definition needed for this markup: ?
You're right, it's not. It
You're right, it's not. It just inherited from my coding habits. But in this case, you don't need it.
A very neat method... and a
A very neat method... and a lovely Drupal theme too! Cheers!
Incidentally, the absolutely positioned element for each column can be nested inside its column so long as the column is positioned and the absolutely positioned element has no left position value. Keeps the HTML code tidy.
This method works great. I
This method works great. I rarely print, but I noticed when I print an example page from this site and my own equal-column-height pages, the formatting and .css are ignored. Is this just an error in my .css, or has anyone else experienced this, too?
My bad, I didn't really paid
My bad, I didn't really paid attention to the print.css
I'll try to find some time to work on this
Wow, thanks for the speedy
Wow, thanks for the speedy reply. Sounds great. In the meantime, I'll work on a print.css that uses conventional columns and see how that goes. The screen versions are really ingenious, though.
Very good job, guy. I have a
Very good job, guy. I have a problem that I supose it has to be with the header and footer problem with headen columns, so is the links in footer doesn't work.
Any suggesiont?
Thanks!