February 26th, 2007 - by Paul OB

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 Lose Weight 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:

  1. <title>Untitled Document</title>
  3. #outer{
  4.     position:relative;
  5.     width:300px;
  6.     background:red;
  7. }
  8. #inner{
  9.     position:absolute;
  10.     left:0;
  11.     top:0;
  12.     height:100%;
  13.     width:100px;
  14.     background:green;
  15. }
  16. #inner2{
  17.     position:absolute;
  18.     left:105px;
  19.     top:0;
  20.     height:100%;
  21.     width:100px;
  22.     background:yellow;
  23. }
  26. <div id="outer">
  27.     <div id="inner">
  28.         <p>This is the text</p>
  29.         <p>This is the text</p>
  30.         <p>This is the text</p>
  31.         <p>This is the text</p>
  32.         <p>This is the text</p>
  33.         <p>This is the text</p>
  34.         <p>This is the text</p>
  35.     </div>
  36.     <div id="inner2">
  37.         <p>This is the text</p>
  38.         <p>This is the text</p>
  39.     </div>
  40. </div>

Running the above code will produce the layout as shown in the image below:

IE and Firefox Comparison

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.


  1. <div id="outer">
  2.     <p>This is the text</p>
  3.     <p>This is the text</p>
  4.     <p>This is the text</p>
  5.     <p>This is the text</p>
  6.     <p>This is the text</p>
  7.     <p>This is the text</p>
  8.     <p>This is the text</p>
  9.     <div id="inner"></div>
  10.     <div id="inner2"></div>
  11. </div>

This is the result:

Firefox and IE absolute columns

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.

  1. <div class="col one"></div>
  2. <div class="col two"></div>
  3. <div class="col three"></div>
  4. </div>

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.


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.


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 Lose Weight 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.

52 Responses to “How to Make Equal Columns in CSS”

1 Alien CSS Homework « kathrynmikeska

[…] to make columns with css” and, after looking through a few sites, I came across this link:  http://www.search-this.com/2007/02/26/how-to-make-equal-columns-in-css/. It appeared helpful, but wasn’t really. It did put my text into columns, but completely […]

2 Paul OB

@kathrynmikeska: You haven’t used any of the techniques in the article and you have loads of errors in your code and you don’t even have a doctype on your page (http://kathrynmikeska.wordpress.com/2012/02/12/alien-css-homework/).

Therefore please do not accuse the article of being unhelpful when you have not used any of the techniques within and are using invalid and badly broken code.

If you need help then please ask and we can fix the problems but just saying the article is unhelpful is rather rude.

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators

Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

Blogs Worth Reading