How do I make equal columns in CSS?
This is one of the more common questions I get asked. My stock answer is that the only element that will base its height on an unrelated element is a table-cell. Unfortunately, IE (including IE7) doesn't support the display:table and display:table-cell properties (although Mozilla and other browsers do), therefore if you want to support most browsers then you can't use display:table and need to resort to other methods.
This article will present to you a nice cross-browser solution to achieving equal columns with CSS.
Let us start by looking at an example of what we will be working towards in this article: Equal Columns without hacks!
I am always interested in experimenting with CSS, trying to achieve layouts that at first don't seem possible. So I’m going to share with you a method that may or may not be useful, but certainly does allow for equal columns without all the associated bugs of other methods. This will serve as a good learning exercise in understanding how certain CSS properties work and in fact how they don't work as they should in some well known browsers.
Absolutely Relative
This technique is based on the fact that if you place an absolute element inside a relative container and set the absolute element to height:100% (or top:0 and bottom:0) it will expand in tune with the parent container (why oh why can't static elements do this - life would be so much easier). The problem is that although the absolute element will expand with the relative parent as required the reverse is not true. If you put content inside your absolute element then it just expands out of the box.
This is easier seen with a little demo:
-
<title>Untitled Document</title>
-
-
#outer{
-
position:relative;
-
width:300px;
-
background:red;
-
}
-
#inner{
-
position:absolute;
-
left:0;
-
top:0;
-
height:100%;
-
width:100px;
-
background:green;
-
}
-
#inner2{
-
position:absolute;
-
left:105px;
-
top:0;
-
height:100%;
-
width:100px;
-
background:yellow;
-
}
-
-
-
<div id="outer">
-
<div id="inner">
-
<p>This is the text</p>
-
<p>This is the text</p>
-
<p>This is the text</p>
-
<p>This is the text</p>
-
<p>This is the text</p>
-
<p>This is the text</p>
-
<p>This is the text</p>
-
</div>
-
<div id="inner2">
-
<p>This is the text</p>
-
<p>This is the text</p>
-
</div>
-
</div>
Running the above code will produce the layout as shown in the image below:

As you can see from the image the browsers are already differing. The reason for this is that IE6 (and under) treat height as a minimum yet will expand the container to encompass its content. The parent container has no height set, therefore its height is auto and because it contains only absolute elements its height is effectively zero because absolute elements are removed from the flow. The absolute elements height is based on 100% height of its parent, which as we have just determined is zero, therefore the absolute elements height should remain at zero also.
This is exactly what Firefox does, as you can see there is no background colour around the text because Firefox is basically ignoring any content that is greater than zero and just lets the content spill out. IE6 on the other hand stretches the green background around the text for the reason already stated. IE does manage to get one thing right, like Firefox, it does not extend the parents background because the absolute element is removed from the flow and has no effect on the parents' dimensions.
So what use is this ?
...an absolute element is removed from the flow and has no effect on the parents' dimensions
So far we have established that an absolute element will have no affect on a parent but what about the reverse? Say we increase the static containers height - what happens to the nested absolute element? Let's find out.
From the code above remove the content from the absolute element and place it inside the static container.
e.g
This is the result:

Hmmm... Can you see what is happening?
Firefox has done exactly what we would expect and has made the absolute elements match the height of the relative parent. But where has the text gone?
The text is still there but it is underneath the absolute column because the absolute elements came later in the html and has been stacked on top by default. We can easily make the text appear on top by manipulating the z-index of each element so that the text has a higher z-index than the background column. To do this we will need to apply position:relative to the texts container (the p tag in this case) as only positioned elements can take a z-index.
...only positioned elements can take a z-index.
So it's looking good in Firefox but alas IE6 has once again broken our dreams. The absolute columns have virtually no height and do not follow the relative parents height at all. Is there a way to overcome this?
Now you see it - Now you don't
Well obviously I have a solution or I wouldn't be writing this!
This solution (while it doesn't borrow exactly from Alex Robinson's one True Layout) does have something in common and that something is that it uses a dimension greater than the browsers window will ever be so that we always get a full length column.
For IE6 and under only (hence the only hack) we will provide an arbitrary height for our absolute columns so that they will extend as the content grows. Unlike the “one true layout" we are not going to use overflow:hidden to hide the bits we don't want to see because that will cause all sorts of problems, not the least of which is the in-page links problem which really is a show stopper.
Instead we are going to place the absolute element at the bottom of the relative parent and give it a height of 1000em. Now instead of the absolute element going down the page it starts at the bottom of our columns and travels up the page and out the top of the browser window.
This means that we only have to hide the content that is above our columns and in a 3-column fixed layout that is simply done by making sure our header is on top and covers the ever-extending upwards columns. We don't need overflow:hidden and we don't need to worry about anything below the columns either (such as a footer).
As already mentioned we only need to do this for IE6 and under because virtually every other browser will implement this correctly without hacks. (I should point out that this technique doesn't work in IE5 mac but works in most other modern browsers without problem.)
Where does the content go?
So now we have 3 absolute columns that will extend as required with the parent container and all that's left to do is to float our real 3 columns on top of those solid background colours. This means that you basically have a completely normal and solidly floated 3 column layout with virtually no hacks or negative margin trickery applied. You simply place at the end of the parent container the 3 divs which hold the background colours and nothing else.
What about Fluid Columns?
Our technique could be used for fluid columns too, but due to rounding errors in IE6 we could not add borders thanks to IE's 1px jog at odd widths and therefore I think the layout is best suited to fixed width columns that we can position exactly. It should be noted that IE6 also has a problem with bottom:0 when the height is an odd number of pixels it will be one pixel out. For this reason its best not to give the relative parent a background colour that would show this.
Drawbacks?
You knew this was coming didn't you? As I see it there are 3 drawbacks that mainly concern IE6 and under:
- First and foremost there is the obvious drawback of the 3 extra non-semantic divs at the end of the layout. However, they are out of the way and don't cause any problems or get in the way of SEO. It should also be noted that the rest of the layout is not compromised at all and there are no extra divs required anywhere else so it is a small price to pay.
- Drawback two is related to IE6 and under and is the fact that we need to use elements above the columns to hide the protruding columns using a background colour and manipulating the z-index. In simple layouts this is no problem but in a complicated header section you would need to ensure that the main header container hides the column tops fully.
- Lastly, for IE6, again there is a problem in that we need to ensure that the header always starts flush with the top of the browser window otherwise the columns background colour will show through.
IE7 behaves in all respects as Firefox for this demo so we can be safe in the knowledge that what we are doing is future-proof (if anything is future-proof) and once IE7 is the main browser we can drop support for IE6 very easily. IE7 has already overtaken Firefox (according to some statistics) so things are moving forward at last.
Re-cap
The premise is simple. We start with a normal floated 3 column layout in all respects. Then to get our full length columns we simply overlay 3 empty absolutely placed divs which will sit under our floated content and provide the column colours. These columns can have full borders and be spaced apart as required.
The drawback is IE6 and under which need an arbitrary height applied at position:absolute; bottom:0; (not top:0) and the height needs to be big enough for all layouts.
If we wanted we could have ten or twenty columns all implemented quite easily and even copy a table layout with cells and rows. However, a table is best used for a table so don't even go there.
Here is a link to the finished layout so just view source to see all the code. As stated, it's just a basic 3 column floated layout with 3 divs added to hold the background colours.
Give with one hand and take away with the other
Although I have shown you how to make equal columns, the article is really more about learning to use CSS. We saw how elements can be manipulated and found out exactly how they should work and also finding out how they don't work in some browsers.
It's only when you put yourself through these sorts of exercises that you can come to terms with what may or may not be possible or feasible before you even start coding. Equal columns are really table behaviour anyway and perhaps those types of concepts should have been left behind with the tables of old and let CSS get on with something new.
Flash CS3 Components from Flashloaded
April 3rd, 2007 at 10:46 am
[…] How to Make Equal Columns in CSS […]
April 23rd, 2007 at 10:46 am
Hi, there!
I found a bug when running IE 5.01 or IE 5.5
The Colors red orange and lila grow over the div. and the footer is only 50% and floated right
I solved that.
adding this to the html and removing the IEFix solves that problem.
Now it works in every IE version =)
But the problem is, this layout is too static for my taste. however have fun with it.
April 23rd, 2007 at 10:48 am
I removed the “!” from the comment, your comments didn’t allow conditional comments.
* html .col{height:99%;}#footer{width:100%;}
* html .col{height:1000em;}
April 23rd, 2007 at 10:49 am
posting of conditional comments didn’t work again..
last try here.
if lte IE 5]>
* html .col{height:99%;}#footer{width:100%;}
endif]
if gte IE 5.5]>
* html .col{height:1000em;}
endif]
April 23rd, 2007 at 2:39 pm
Hi Xsss4hell,
Thanks for your comments.
I didn’t bother confusing things in the demo with hacks for ie5 but it can simply be fixed with the following.
* html #footer,* html #header {height:1px}
Its just the usual “haslayout” issues again
No need to separate the styles as that works for all IE6 and under perfectly
April 30th, 2007 at 3:28 pm
Just wanted to say thank you Paul!
This is by far the best article on the problem. The solution is neat and easy to use and solves my problem perfectly. Although I modified it for a two-column layout, I can see that this extends nicely to other types of layouts. Exactly what a near-perfect solution should do.
Thank you!
May 1st, 2007 at 4:01 am
Glad you found it useful
May 19th, 2007 at 12:21 pm
What technique would you recommend for a fluid layout like this?
Fluid center column
Fixed-width side columns
Center column first in source code
I’m leaning towards the method that uses a center column with borders the color and width of the side columns, and floats the side columns over the borders. It sounds more-or-less hack free, from what I’ve read. Would you agree, or do you recommend another approach?
May 19th, 2007 at 3:12 pm
Hi,
I have a demo here that has a fluid centre and fixed side columns and doesn’t need images for the columns and can also be bordered unlike other methods, including the one you mentioned.
http://www.pmob.co.uk/temp/3col/3col-fixed-side-01.htm
However its not content first so I just converted it quickly but not sure how stable it will be. It is also a little more complicated than other methods so that may be a big drawback.
http://www.pmob.co.uk/temp/3col/3col-content-first.htm
Be wary of all the other methods that float completely into the side with negative margins because they don’t work in all mozilla from version 1.6 and backwards.
This is because the negative margin is equal to the width and therefore the element has no width at all (because a total width is calculated including the margins)and therefore gets ignored as though its an absolute element.
My examples use a 1px overlap and work in all those versions.
However, even though I have a lot of demos like this I still tend to use the method of 2 background images on outer containers and use three simple floats without any hacks at all, which will work most everywhere
May 19th, 2007 at 5:00 pm
Hi Paul. I discovered your demos a few days ago, when searching google (three+column+layouts — you were #10 on page 1).
One of your demos does what I was asking about — http://www.pmob.co.uk/temp/3colfixedtest_sourcenone.htm , but with the IE7 problems I assumed it wouldn’t work anymore, so that’s why I started looking at the wide border method (described in a recent article at alistapart).
Thanks! Wow, ask and you shall receive. You’re right, that does look a little complicated for my basic understanding of css. But it’ll be good for me to study it and figure out how it works.
May 20th, 2007 at 2:44 am
HI Dean,
Hope you find it useful anyway.
The first example seems to work OK in IE7 unless there’s something I haven’t noticed. Most of the demos have been updated for IE7 but I haven’t got around to them all yet.
They are only usually minor problems “haslayout” problems anyway.
It is good to study it so that you understand how it works and then you can adapt it to suit your purpose
May 21st, 2007 at 10:27 pm
Paul wrote:
That sounds like the approach I should begin with for now. I don’t really need ‘full-length’ columns at the moment — just 3 columns, with fixed width side columns and the center first in the source.
Is there a trick to it, other than keeping the negative margins less than the width on the side columns? Can you point me to an example that’s coded correctly, or is it simple enough that I should just try writing one from scratch?
Your example for a 3 column Fluid Simple layout is close to what I’m looking for. It looks like it should be easy to modify so that the side columns are fixed and the center content comes first. I’ll see what I can come up.
May 22nd, 2007 at 8:27 am
Hi Dean,
If you are looking for source order layouts then there are a load here:
http://blog.html.it/layoutgala/
However all the first 20 or so of them with the fluid column width will fail in mozilla 1.6 and under due to the reasons I mentioned earlier.
If you want source order then the method used in the example you linked to is probably more robust but involves a little extra mark up to achieve.
http://www.pmob.co.uk/temp/3colfixedtest_sourcenone.htm
Most content first example involve using negative margins and can be quite complicated to understand at times. Three fixed with columns are easy to move around but fluid columns are a little more awkward.
May 22nd, 2007 at 12:37 pm
Paul wrote:
Thanks, Paul. I came to the same conclusion last night after some experimentation and study. Fluid width would be nice, but I decided to start with (gasp ;)) Fixed-width for now. I need a layout that’s easy to use based on my current understanding of css, and safe for public consumption (bug-free) on common browsers.
Later when I have more time I’ll study the fluid-layout methods. Between your tutorials here, on pmob.co.uk, and sitepoint, there’s certainly plenty of study materials to keep me busy! Thanks again for sharing your knowledge. I appreciate your help.
p.s. All the articles here on search-this are excellent. Discovering this site was a good find. Thank you, everybody.
July 20th, 2007 at 5:13 pm
So…. remind me what was so bad about tables??
July 21st, 2007 at 3:10 am
@ Bob http://www.hotdesign.com/seybold/
[quote=me]
“Equal columns are really table behaviour anyway and perhaps those types of concepts should have been left behind with the tables of old ….
[/quote]
September 6th, 2007 at 6:48 am
Hi,
I’m probably missing something, but I’ve just viewed the source code for the equal columns with space at top of page, and I noticed that some of the css rules refer to a class of .col but I couldn’t find any elements in the html code with this class label.
I’m just trying to study the code to find out how it all works but as I said I could be missing something. Can someone help me out, point out which html element has a class of .col?
Thanks
September 6th, 2007 at 7:58 am
Hi,
If you look just above the footer there are three divs with a class of .col.
class=”col one”
class=”col two”
class=”col three”
They also have another class added for addition styling. If you don’t understand multiple classes then see the multiple class example article I posted
September 6th, 2007 at 11:13 am
Thanks for that. I don’t actually understand multiple classes - can you provide a link to your multiple classes example b/c I can’t locate it myself.
Also it’s really hard to understand what the styles for the .clearer class do - can you clarify?
September 6th, 2007 at 2:04 pm
The multiple class article is here:
http://www.search-this.com/2007/04/25/optimize-your-css-with-multi-class-elements/
To understand clearing see the recent article here under the section “where’s my background gone”:
http://www.search-this.com/2007/09/05/lets-be-clear-about-this/
October 17th, 2007 at 9:47 am
I’m confused - this explanation just seems to end without showing the final HTML and related styles. Where is the CSS for “col one, col two..” etc…?
October 17th, 2007 at 10:19 am
Hi,
Sorry it wasn’t clear enough but it’s probably best if you view source of the main example to see the code in full.
e.g.
http://www.pmob.co.uk/search-this/absolute-columns2.htm
The css for the column colours is as follows.
.col{
width:200px;
position:absolute;
z-index:0;
left:10px;
bottom:0;
border:1px solid #000;
border-top:none;
}
.one{background:red;}
.two{background:#FF6600;left:222px;width:334px;}
.three{background:#CC3399;left:568px;}
Hope that hlps but shout if you have any questions.
October 17th, 2007 at 10:50 am
ahh - thanks! I didn’t know where the final example was
October 25th, 2007 at 2:02 pm
I’ve added some fluid examples and some fluid and fixed examples here:
http://www.pmob.co.uk/temp/3col-absolute-columns-fluid.htm
http://www.pmob.co.uk/temp/3col-absolute-columns-fluid-fixed.htm
January 9th, 2008 at 1:38 pm
Thanks for this great post!!!