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 CSS Rewind: Great CSS Articles

[…] How to Make Equal Columns in CSS […]

2 Xsss4hell

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.

3 Xsss4hell

I removed the “!” from the comment, your comments didn’t allow conditional comments.

* html .col{height:99%;}#footer{width:100%;}
* html .col{height:1000em;}

4 Xsss4hell

posting of conditional comments didn’t work again..
last try here.

if lte IE 5]>
* html .col{height:99%;}#footer{width:100%;}

if gte IE 5.5]>
* html .col{height:1000em;}

5 Paul OB

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 🙂

6 Jose de Leon

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!

7 Paul OB

Glad you found it useful 🙂

8 Dean

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?

9 Paul OB


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.


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.


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 🙂

10 Dean

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).

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.


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.

11 Paul OB

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 🙂

12 Dean

Paul wrote:

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 🙂

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.

13 Paul OB

Hi Dean,

If you are looking for source order layouts then there are a load here:


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.


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.

14 Dean

Paul wrote:

Most content first examples involve using negative margins and can be quite complicated to understand at times. Three fixed width columns are easy to move around but fluid columns are a little more awkward.

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.

15 bob

So…. remind me what was so bad about tables??

16 Paul OB

@ Bob http://www.hotdesign.com/seybold/

“Equal columns are really table behaviour anyway and perhaps those types of concepts should have been left behind with the tables of old ….

17 gwh


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?


18 Paul OB


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 🙂

19 gwh

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?

20 Paul OB

The multiple class article is here:

To understand clearing see the recent article here under the section “where’s my background gone”:

21 Where are the styles

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…?

22 Paul OB


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.



The css for the column colours is as follows.

border:1px solid #000;

Hope that hlps but shout if you have any questions.

23 thanks

ahh – thanks! I didn’t know where the final example was 🙂

24 Paul OB
25 readywpthemes

Thanks for this great post!!!

26 Christopher Thomas

So what happens when you want to put content at the top of the column instead of just at the bottom?

all you seemed to have done, is reversed the faux columns idea and reversed the direction of the expansion and use the browser window to constrain the expansion.

Now, unless I’ve missed something, I hope I didnt, this actually doesnt solve anything that can’t already been solved.

So what does this technique bring to the table over faux columns? except the removal of the overflow attribute?

27 Paul OB

@Christopher Thomas – I think you should read the article again as your comments make no sense.:)

The content does not go at the bottom of the columns it is placed in the normal flow of the document in the floated columns as usual.

Its only the background colours that are placed at the bottom of the document and no content is placed in these as they are just color overlays as explained in the article.

The “faux Column” technique uses background images for its effect and can’t be used on three fluid columns like my method which uses no images at all.

If you were talking about “the one true layout” then my layout doesn’t suffer from the in-page links problem (which is a show stopper right from the start), it doesn’t need massive padding and margins), is easy to use and most importantly doesn’t need any hacks apart from the one hack for ie6 only.

Although its not shown in the article overflow can be used on the columns to hide the overflow for ie6 without causing the in page links that the “one true layout” exhibits.

All in all it was a thoroughly innovative and useful technique and as the article is almost 2 years old the techniques are now well tested and work well without hitch.

I suggest that you research the details a bit more thoroughly in future before making bland comments like above.

28 Nick Fitzsimons

This is an invaluable technique. Just this afternoon, it enabled me to sort out a problem for a client, not with a quick-and-dirty fix but with a stable solution that will make life easier for them when updating their site in the future.

Being able to create equal-height columns within other content, rather than the usual three-column page, is a demonstration of its value.

FYI, the only problem I encountered was in IE 6 and IE 7 where a containing element needed to have “position: relative;” set to make things fall into place. This didn’t affect any other browser, so there was no need to use hacks or conditional comments.

If anybody else is having trouble with this technique within a moderately complex combination of structure and styling, try “position: relative;” on an appropriate containing element further out from the specific markup relating to this technique to see if it helps.

29 Paul OB

Hi Nick, Glad you found it useful and thanks for sharing your findings. IE6 always has a trick up its sleeve to thwart us at some stage but most problems can be overcome with a bit of thought 🙂

30 Professor C

This post is great… up to the point that you start to discuss the solution. At this particular moment, pmob.co.uk seems to be completely down and I can’t view any of the finished examples. Pointing out why you can’t depend on linking to external resources when making posts like this. 🙁

Hopefully pmob will come back soon.

31 Paul OB

Sorry the site was down 🙂 It’s back up now and you are correct that it would have been better to include the full code at the end of the post also.

[…] did some googling and found a good link to a demonstration of exactly what I needed to do. Their article describing how to implement this, however, was a little hard for me to […]

33 mark simmons

Great! Many thanks for this. Just modified the code to give me the fixed width 2 col presentation I’ve been looking for ages without resorting to either tables or hacks. It appears to work a treat in IE5,6,7 and FF3 tested so far. I’ve also added a min-height: 500 to the #left so that when I have multiple pages that don’t exceed this height then we don’t get the jumping effect when switching between pages.

– Mark.

34 Sony KDL46VE5

Very smart, bravo.

I’d say this method is an alternative to faux columns, but doesn’t replace it.

35 Michael J

This method works great until you generate content via Javascript (such as with AJAX). After the page loads, if you change the content within the containing divs at all, the content can end up displaying beyond the bottom of the parent div in IE7 (and probably IE6). Obviously, this has to do with the parent div having absolute positioning. Changing the positioning to relative just messes up the layout. It works fine in IE8 and FF, but a LOT of people are still using IE7.

Any thoughts on how to fix this?

36 Paul OB

Hi Michael,

I’d need to see an example of where this is happening but I don’t believe it has anything specifically to do with my technique but the fact that IE always forgets where some absolute elements are when you insert dynamic content.

The same issue happens in absolutely placed footers at the bottom of a document.

One solution was that after the content was inserted the screen needed to be refreshed to make everything click back into place. I vaguely remember years ago just jogging the screen size dynamically back and forth by a pixel to get the same effect.

What happens if you grab the corner of the browser after you have inserted your content does everything click back into position?

If you want to post a link then I’ll take a look and see if there is an easy fix.

37 Nick Fitzsimons

@Michael J: one technique I’ve found to bring IE 6 and 7 to heel under such circumstances is to assign a value to the className property of the outermost containing element; this prompts IE’s rendering engine to reflow the contents (in case the change of className has affected the styling of the element and/or its descendants) and therefore repaint them correctly… most of the time 🙂

Assuming you have a reference to the outermost container in a variable named “outer” then a simple

outer.className = outer.className;

is sufficient – the className doesn’t actually have to change for this to work.

If this doesn’t seem to do the trick, you may need to move out (or even in) an element or two to apply this trigger, but a bit of experimentation should get you there.

I have encountered one case (not using the specific techniques Paul describes here) where this trigger fixed IE 6 but triggered an even worse bug in IE 7, but that was a pretty complex layout, and normally it does the trick.

38 Paul OB

Thanks for the tip Nick that will come in very useful 🙂

I’ve just done a bit of testing on the equal column layout and a dynamic hide and show does trigger the bug Michael mentioned and as I have seen before with absolute elements.

However just changing a couple of little things around will get IE6 and 7 to work nicely. The main problem was the empty clearer div that gained layout before the absoloute columns html that triggered the redraw bug.

I used a different clearing mechanism and the code works fine now.

Here’s a live example.


39 Paul OB

BTW Nick – your method also worked without having to change the html 🙂

40 Michael J

Excellent! Thank you so much for the help! Everything is working great now.

41 web development

thanks! solved my problem

42 jayaprakash

How to make text run bottom-to-top in CSS?

43 Paul OB

@jayaprakash: It depends on what you mean.

You could absolutely place an element at the bottom of another element and the text would run upwards.

e.g. (some very old demos)


44 Keith

This is a great tutorial, but it begs the question: Why not just use tables (at least for the column layout)? Sure they are antiquated, but this seems a perfect fit. It might not currently “look pretty” to use tables within a environment, but the functionality is superior. In most cases, it would require less code than making hacks that will work with all browsers. No?

45 Jamie Hill

Another solution that may be of interest which works in Safari, Chrome, Firefox and IE right back to IE6: http://thelucid.com/2010/12/03/the-solution-to-fluid-inconsistencies-and-equal-height-columns/

46 Paul OB

Hi Jamie,

Thanks for your link which is quite interesting especially the percentage based widths method. I should point out though that it fails in Opera because opera doesn’t honour fractions of a percentage so there are big gaps in opera although there’s little you can do about that.

The equal column method is roughly based on the same concept as the old article above with the absolute overlays except for using :after to create the absolute overlay instead of an extra html element.

While I think that it is a neat concept it leaves IE6 and 7 out in the cold unlike my method which just needs one empty extra html element for ie6 and 7 to work nicely.

The main drawback of your method is that it suffers from the same problem as “the one true layout” and you can’t have any in-page links or your content is cut off when the target is reached.

This is a showstopper for me and doesn’t happen in my example here which works back to ie5 with equal columns.


47 Jamie Hill

@paul If you stick to whole percentages Opera will work fine, unfortunately there is no workaround for it’s lack of fractional percentage support. As the for the equal height technique failing with links, I’ve not had a problem with this as the additional element has a z-index of -1 allowing the links to be clickable.

48 Paul OB

Hi Jamie,

I replied on your site but not sure if the post was accepted as it just seems to time out on me (it did that yesterday also). Therefore I have reproduced the post in part below.

Yes the Opera problem with percentages has always been like that ever since the year dot and I guess that it’s not something that’s likely to get fixed soon 🙂 I documented it about 8 years ago in this ol and tired demo(http://www.pmob.co.uk/temp/hozinlinemenu.htm).

Regarding the link problem , perhaps I wasn’t that clear but the problem is not with clicking the links but with “in-page” links (i.e. links that are reached via a fragment identifier).

If you have a link in your page that goes further down the same page and inside one of those columns (e.g. …a href=”#info”… ) then you will find that the page scrolls to the link as requested but any content that was previously above the link is completely cut-off and unreachable and unusable.

This is the same problem as in the one true layout and the reason why its use can’t be trusted but all for the simplest of scenarios.

I’ve put a demo of your code here with the fragment identifiers added and you can see for yourself if you click the link in column 5.

In all browsers (except ie6 and 7) the destination is scrolled to but that effectively makes all the content above disappear and makes the page unusable.

BTW, I’m not trying to be negative as I think it’s great that you are trying these things out as that’s the way these things move forward :).

49 3 Col Layout Issue - SitePoint Forums

[…] the wrapper always contains the three columns then it will always be the right height. There are other methods of making equal columns but the above is still the easiest for a fixed width layout. […]

50 Gatis

and if you want content floating from one column to another, I have a simple CSS3 script: http://inter.lv/tool/23/css3-columns.

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

You need to download the Flash player from Adobe

Other Sites