Four Methods to Create Equal Height Columns


Four Methods to Create Equal Height Columns
Back when tables were used for layouts, creating equal height columns was very simple. All you had to do was create three cells in a row and you have a layout with equal height columns. The method for creating equal height columns isn’t as straightforward when you use CSS for layouts.

This article discusses some methods to create equal height columns that work on all major web browsers (including the infamous IE6). All of these methods show how to create a three column layout.

Create a layout in which all the three columns assume the height of the tallest column.

Equal Heights: Before/After

Method 1: Using display: table Attribute

In this method we use a list or one div enclosing a set of <div>s (one for each column). The enclosing div is given a display: table attribute and each enclosed div is given a display: table-cell attribute.

I’ll discuss this with an example:

Here’s the markup for this technique

<div class=â€baseâ€>
 <ul class=â€base-rowâ€>
 <li class="cell1"><div class="content1" >.....Lots of  Content....</div></li>
 <li class="cell1"><div class="content2">.....Lots of  content....</div></li>
 <li class="cell1"><div class="content3">.....Lots of  content....</div></li>
 </ul>
 </div>

Here’s the CSS

.base {
 /*make it 100% width and a minimum of 1000px width*/
 width: auto;
 margin-left: 0px;
 margin-right: 0px;
 min-width: 1000px;
 padding: 0px;
display:table;
 }
.base-row {
 Display: table-row;
 }
.base li {
 display: table-cell;
 width: 33%;
 }
.cell1 {
 background-color: #f00;
 }
.cell2 {
 background-color: #0f0;
 }
.cell3 {
 background-color: #00f;
 }

Advantage:

It is very simple and easy to implement. It is far simpler than most other methods. This can save you a LOT of headache and time.

A margin (the equivalent of a cellspacing in table layouts) cannot be applied to each cell. This can be overcome by using a border of white color (or your background color) of a suitable width to mimic a cell spacing.

Disadvantage:

This method doesn’t work on IE7 and below. It may be a long time (when IE7 becomes the new IE6 or IE5) before we can safely use this technique. But it is useful when you can be certain IE7 will not be used by your audience such as in corporate Intranets.

See this method in action

Method 2: Using JavaScript

This method relies on JavaScript to set the height attribute of all the columns in the layout to the height of the tallest column. In this example, I have used jQuery to equalize the columns.

Create the HTML for the three columns:

<div class=â€containerâ€>
 <div  class=â€leftsidebarâ€> … Lots Of Content … </div>
 <div class=â€contentâ€> ….  Lots Of Content … </div>
 <div  class=â€rightsidebarâ€> … Lots Of Content … </div>
 </div>

Put them next to each other and aligns them in center them.

.container {
 Width: 900px;
 Margin-left: auto;
 Margin-right: auto;
 }
.leftsidebar {
 Float: left;
 Width: 33%;
 }
 . content {
 Float: left;
 Width: 33%;
 }
. content {
 Float: left;
 Width: 33%;
 }

JavaScript (using jQuery):

function setEqualHeight(columns)
 {
 var tallestcolumn = 0;
 columns.each(
 function()
 {
 currentHeight = $(this).height();
 if(currentHeight > tallestcolumn)
 {
 tallestcolumn  = currentHeight;
 }
 }
 );
 columns.height(tallestcolumn);
 }
$(document).ready(function() {
 setEqualHeight($(".container  > div"));
});

You can put the JavaScript in a separate file and attach it to your HTML or use it inline but make sure you also attach jquery to the HTML page and this script is called after jquery is attached.
The code you need to change is the css class of the div elements that make the columns. In this example it is:

.container > div

You may replace the above with the css class that describes all the <div> elements of the columns. For example: you may add a class to each of the three columns and use that instead for simplicity.

Advantage:

Advantage of this method is that there is no CSS involved in making the columns get equal heights. It also works in every major browser

Disadvantage:

If JavaScript is disabled, the columns will not be of equal height. This shouldn’t bother you because many essential websites today need JavaScript function therefore very few users will have JavaScript disabled. Even if it is disabled, the site will not become unusable.

See this method in action

Method 3: Faux Columns

This method is the earliest known solution to the equal columns problem. This method involves the use of a background image that has one region for each column’s background color. The columns are positioned just above the background color regions that belong to them. After the markup of all three columns is a <div> element which takes a clear: both attribute making the container background stretch to the tallest columnThe background is repeated vertically so it appears like the three columns are of equal height.

The HTML:

<div class=â€containerâ€>
<div class=â€leftâ€></div>
<div  class=â€contentâ€></div>
<div class=â€rightâ€></div>
<div class=â€clearerâ€></div>
</div>

The CSS:

.container {
background-image: tile.png;
background-repeat: repeat-y;
width: 900px;
margin-left: auto;
margin-right: auto;

}

.leftsidebar {
float: left;
width: 200px;
}

.content {
float: left;
width: 400px;
}

.right {
float:left;
width: 300px;
}

.clearer {
clear: both;
}

Advantage:

It is simple, doesn’t need much CSS and can be easily implemented.

Disadvantage:

You cannot use fluid width equal height columns if you have more than two columns as we are using an image.

See this method in action

Method 4: Using Separate Background Color <div> elements

In this method we use a separate <div> element for the background of each column. Any div element takes the height of the largest element it encloses. This method works based on that principle.

The HTML:

<div class=â€rightbackâ€>
<div class=â€contentbackâ€>
<div class=â€leftbackâ€>
<div  class=â€leftsidebarâ€>…Lots Of Content…</div>
<div class=â€contentâ€>  …Lots Of Content…</div>
<div  class=â€rightsidebarâ€> …Lots Of Content…</div>
</div>
</div>
</div>

The CSS:

.rightback  {
width: 100%;
float:left;
background-color: green;
overflow:hidden;
position:relative;
}
.contentback  {
float:left;
background-color:blue;
width: 100%;
position:relative;
right: 300px;    /* width of right sidebar */
}
.leftback  {
width: 100%;
position:relative;
right: 400px; /* width of the  content area */
float:left;
background-color: #f00;
}

.container  {
width: 900px;
margin-left: auto;
margin-right:auto;
}

.leftsidebar  {
float:left;
width: 200px;
overflow:hidden;
position:relative;
left: 700px;
}

.content  {
float:left;
width: 400px;
overflow:hidden;
position:relative;
left: 700px;
}

.rightsidebar  {
float:left;
overflow:hidden;
width: 300px;
background-color:#333;
position:relative;
left: 700px;
}

Looks complicated doesn’t it? Once you understand how it works it becomes very simple. The technique is summed up in the following 5 points:

  1. .rightback, .contentback, and .leftback are the enclosing <div> elements .leftsidebar, .content and .rightsidebar are the <div> elements that have the content.
  2. Each enclosing <div> corresponds to the background (colour and/or image) of a region. In this example .leftback for .leftsidebar, .contentback for .content and .rightback for .rightsidebar
  3. Except the outermost one (corresponding to the right most column) all the enclosing <div> elements are given a right offset equal to the width of the element to the right of the element to which it provides background colour. In this example .contentback (provides background colour for .content) is moved left by 300px (which is the width of .rightsidebar). (See image below)
  4. The .left sidebar, .content and .rightsidebar are floated left and given some width.
  5. They are given a left offset equal to the sum of widths of all the columns except the left most one. Here it is = width of rightsidebar (300px) and content (400px) = 700px.( B+G)

The image below shows how the enclosing <div> elements,  .rightback, .contentback and .leftback, are displaced. The bottom most is the .rigthback element and the top most being the .leftback element.

The dashed lines represent the viewable content as the .rightback element crops the other backgrounds using an overflow: hidden attribute.

In the following image, the black lines below the red line are the content <div> elements .leftsidebar, .content and .rightsidebar as they will appear if they are given float:left and given appropriate widths to fill the entire width.

All the three content elements are given a left offset of C using relative positioning.
C = B+G (see image above)

This method is discussed in much detail in this article.

Advantage:

It works in every browser including Internet Explorer 6. This method doesn’t need JavaScript and is accomplished purely through CSS and HTML.

Disadvantage:

It is not as straightforward as the other methods. It is a little tricky to understand. But it is can be easily created for any number of columns once you understand how to do it.

See this method in action (3 columns) | Same technique used to create four column layout

Final Note

Each method has its advantage and disadvantage but you are most likely to find the last method to work in every browser if you are looking for the purest CSS solution to the equal height columns problem.

Interested in writing a guest post for us like Raja? We’d love to have you! Here’s how to get started.

  • Stumble It!
  • Bookmark It!
  • Tweet it!

About Raja Sekharan

Raja Sekharan is a freelance developer specializing in creating web applications and cross platform desktop applications. He shows how to quickly develop websites and applications using Drupal and Wordpress at Expedition Post

 

Discussion

  1. Clive Walker

    July 9th, 2009 at 1:09 PM

    For smaller page areas, it could be worth considering the CSS3 multi-column layout module. Not supported in all browsers yet, I know – but I think there is a JavaScript method that overcomes the browser support limitation.

  2. Clive Walker

    July 9th, 2009 at 1:24 PM

    Forgot to say, I’m writing a blog post on the multi-column method. If you are interested, will post it here when done.

  3. Internetlösungen

    July 9th, 2009 at 4:02 PM

    Thanks for this great tutorial. It helped me alot to proofe my CSS Skills.

  4. Rajasekharan

    July 9th, 2009 at 10:10 PM

    Internetosungen, Glad to know you liked it.
    .-= Rajasekharan´s last blog ..Drupal Module: Twitter Block – Add Your Twitter Feed To Your Drupal Website =-.

  5. Mike

    July 10th, 2009 at 7:38 AM

    Method 1. The list items should be wrapped in ul tags, and the demo links are all mixed up.

  6. Florian

    July 10th, 2009 at 8:15 AM

    What about a giant padding-bottom and giant negative margin-bottom with overflow:hidden container? It’s the easiest way in my opinion. Seen here: http://www.positioniseverything.net/articles/onetruelayout/equalheight

  7. Zach Dunn

    July 10th, 2009 at 8:25 AM

    @Mike

    Thanks for the tip off, I’ve updated the post to reflect the changes.

  8. Michele

    July 10th, 2009 at 10:35 AM

    This is what I use: http://www.alistapart.com/articles/holygrail

  9. Web Design Mumbai

    July 10th, 2009 at 12:20 PM

    Nice post. Creating a layout does give a lot of problems in CSS.

  10. David Hucklesby

    July 10th, 2009 at 9:11 PM

    @Michele – that’s the same as in Florian’s article, I believe.
    Another method is “Companion Columns” -
    http://www.satzansatz.de/cssd/companions.html

  11. Nick

    July 11th, 2009 at 9:09 AM

    Another method:
    http://chikuyonok.ru/playground/cols/ – example
    http://www.vtb24.ru/ – work site

  12. Artisan

    July 11th, 2009 at 11:38 AM

    I love the final method. Thank you for these tricks!

  13. DHX

    July 14th, 2009 at 4:04 AM

    *starts a forcefield around around himself*
    Or you could just use TABLE for it :)

  14. Marc

    July 14th, 2009 at 5:34 PM

    Just what I was looking for a half an hour ago.. I was going crazy!

    @DHX

    First of all> hahahahaha Nice one brotha
    Second>Luckily I can use TABLES every day on my work. For Styling an email for our clients:D

  15. Zach Dunn

    July 15th, 2009 at 7:53 PM

    @DHX

    You’re absolutely right. We could call it “Method 5: How to lose the respect of your web peers”

  16. Dicky

    July 16th, 2009 at 8:45 PM

    Great tutorial! I am now using the jQuery method. Simple and easy.
    .-= Dicky´s last blog ..80 Smart And Creative Advertisements That You Should Bookmark And Stumble =-.

  17. Dimitris

    July 17th, 2009 at 3:18 AM

    (Editors Note: Demetris is not the audience you (or anyone) should be developing for. Take what he says as a grain of salt. One of these four methods should suit almost any design. )

    Method 1: Ok but not supported by the most popular browser. FAIL

    Method 2: Requires javascript and jquery. FAIL

    Method 3: Hard coded into an image! EPIC FAIL

    Method 4: What ever happened to “semantic markup”? FAIL

    HolyGrail: I pity thou who have gone into such painfull lengths. However I pity more those who have hired you. Had I been your boss, you would be fired for throwing unnecessary complextity into a simple problem, solely to suttisfy your tableless ego.

  18. Raja Sekharan

    July 17th, 2009 at 5:05 AM

    @Dimitris

    All the more reasons why you are not (or ever will be) my (or anyone’s) boss. Apparently Tableless-less-ness will be more semantic right?
    .-= Raja Sekharan´s last blog ..How To Add A Administration Page In Wordpress =-.

  19. Dimitris

    July 17th, 2009 at 5:57 AM

    Guess which one looks both better AND more correct semanticaly given the context of this blog post.

    …Lots Of Content…
    …Lots Of Content…
    …Lots Of Content…

    …Lots Of Content…
    …Lots Of Content…
    …Lots Of Content…

    Certainly you wouldn’t get a job from me. My associates are rated in terms of their productivity and efficiency.

  20. Zach Dunn

    July 17th, 2009 at 7:09 AM

    @Dimitris

    I don’t know what prompted you to write such negative comments, but we don’t run that kind of ship here. I can’t tell if you’re a table advocate or else, but it’s irrelevant. The web niche doesn’t need your “pity”, although is seems like it could benefit from some tact in keeping your mouth shut.

  21. zalun

    July 17th, 2009 at 7:21 AM

    Thanks for the summary.
    You have a bug in the last example’s CSS. rightright is not valid CSS parameter.
    .-= zalun´s last blog ..New/old passion =-.

  22. Louis

    July 17th, 2009 at 2:53 PM

    Nice variety of methods here. I wrote a pure JavaScript method as well, which works well cross-browser, and also takes into consideration any border-thickness and padding: Equal Height Columns with JavaScript.
    .-= Louis´s last blog ..Add a Custom “Trendy†Border Around Blog Images With CSS & JavaScript =-.

  23. Dimitris

    July 17th, 2009 at 3:57 PM

    I see, you (author) edited MY comment and put a retarded remark downplaying my opinion because you didn’t like it. I hadn’t realized I was talking to such a wuss!

  24. Zach Dunn

    July 17th, 2009 at 4:14 PM

    @Dimitris

    That was actually my doing, and not Raja’s.

    See here’s the thing Dimitris: we’re entirely fine with having different opinions, but your comments go a step beyond that. There’s no reason to berate the author with a comment that has zero insight as to possible alternatives. You’re entitled to your opinion, but don’t tell someone who’s worked hard on an article that you pity a person who would follow his advice. That’s called being a dick… and we don’t like that here.

  25. Jeremy

    July 30th, 2009 at 9:15 AM

    Nice summary here of all the methods! I put in place the “faux columns” method. Worked great… but I had to align horizontally buttons at the bottom of each column. And with the “faux columns” method, the columns look the same height but are not. So I guess I’ll go for the jQuery option here.
    .-= Jeremy´s last blog ..Drag and drop en HTML 5 =-.

  26. Jeremy

    July 30th, 2009 at 9:38 AM

    I’m using multiple lines with 3 columns each. For example, I have 3 lines and 3 columns ( = 9 boxes in total). With the JS, ALL the boxes have the same height. So if the last box of the last line has plenty of text, the boxes on the 1st line will be far too big.

    So I want to implement the JS method for EACH line. I tried to do it with this code but it doesn’t work :
    function setEqualHeight(container,columns)
    {
    container.each(
    function()
    {
    var tallestcolumn = 0;
    columns.each(
    function()
    {
    currentHeight = $(this).height();
    if(currentHeight > tallestcolumn)
    {
    tallestcolumn = currentHeight;
    }
    }
    )
    columns.height(tallestcolumn);
    }
    )
    }
    $(document).ready(function() {
    setEqualHeight($(“.mosa-list”),$(“.mosa-box”));
    });

    Maybe you’ll see what I’m doing wrong here. Anyway, thanks for any help.
    .-= Jeremy´s last blog ..Drag and drop en HTML 5 =-.

  27. sravkum

    August 1st, 2009 at 2:26 AM

    wow this is really a good stuff – useful
    .-= sravkum´s last blog ..Rakhi ka Swayamwar.. marriage with a difference? =-.

  28. bang

    August 3rd, 2009 at 9:59 AM

    wouldnt “minimum height” be easier ?
    ok this way it will depend of the content, but i found it way easier and lame browsers friendly.
    and its just 1 css line to add.

  29. bang

    August 3rd, 2009 at 10:00 AM

    min-height *

  30. Raja Sekharan

    August 3rd, 2009 at 12:48 PM

    @bang, I assume you mean adding a min-height attribute to all three (or more) columns. Suppose there are three columns A, B and C. If column A has much content and needs more vertical space than the min-height value, it will not automatically resize columns B and C to the height of A. Columns B and C will still be at the height specified by the min-height attribute. But it might work when you are sure the content will never overflow past the min-height.
    .-= Raja Sekharan´s last blog ..How To Add A Administration Page In Wordpress =-.

  31. bang

    August 4th, 2009 at 10:24 AM

    yep, exactly what i meant.
    but of course it all depend ur content.

  32. Bradford Sherrill

    August 4th, 2009 at 11:08 AM

    Nice post, JS + CSS is the way to go for cross-browser compatibility

  33. webzhao

    August 6th, 2009 at 3:11 AM

    { height:100%;_height:99999px; }
    I think that’s the most simple solution

  34. David

    August 12th, 2009 at 12:29 PM

    OK. This is a tangent but is related. I have a table as follows:

    Label_Header|Column1|Column2||Column3|Column4
    Row_Label_1|R1_Data1|R1_Data2||R1_Data3|R1_Data4
    Row_Label_2|R2_Data1|R2_Data2||R2_Data3|R2_Data4

    This is actually constructed with an outer table with 1 row. In the first column of this table is an inner table containing “Label_Header|Column1|Column2″ and the corresponding data. The second column of the outer table contains an inner table contain “Column3|Column4″ and the corresponding table. (You can see the html for this here: http://drop.io/jip2adu/asset/mriweb-dll-htm).

    How do I make the rows of each table the same height?
    (Please note that due to the way this file is generated, I must use the table structure as it appears)

    Any help is greatly appreciated!

    David

  35. john

    August 14th, 2009 at 4:30 AM

    The columns are not aligned properly on IE8, IE6 and FF 3.5 browsers. What about if the browser disable or doesn’t have JavaScript, then this technique is flawed. Layouts like this shouldn’t rely on JavaScript.

  36. Michelle Klann

    August 23rd, 2009 at 12:29 PM

    I am definitely going to bookmark this article!

    I think I would opt for method 3. Even though it may be more cumbersome and time consuming – it seems to be the best solution for all browsers and browser settings. Thanks for taking the time to put this together! I’ve been trying to overcome this exact issue for some time now.

  37. Enrique Ramírez

    August 23rd, 2009 at 12:54 PM

    Besides number 1, these all seem to be about faking equal height columns than to actually making them. The downside of this is that, for complex layouts (or layouts with complex backgrounds) most of these won’t work.

    There are two more methods that you didn’t mention:

    1) First one works on very specific designs. As long as the parent element has a set height, setting the children’s height will work as expected. An example would be having a #parent with height: 600px; then the two columns can have a height: 100% and it’ll work.

    Of course, we don’t want fixed heights anywhere most of the time. Then again, we can use the html and body tags for this. Setting body, html {height: 100%} will do wonders. Explaining further would be kinda hard, but here’s an example: http://blog.enrique-ramirez.com/wp-content/uploads/2007/08/css-columns-100-porciento.html (sorry, it’s in spanish).

    2) The second one is fairly more complex (actually, LOTS more). I’ll try my best to explain: #parent has 2 children: #one and #two. CSS would be something like this:

    #parent {overflow: hidden}
    #one, #two {padding-top: 32768px; margin-top: -32768px}

    That’s it. Basically, we’re giving a HUGE padding-top to the columns, making thems tretch pretty much everything we’ll need, and then using a margin-top to bring back the content. As to why we need to use 32768? Well, IE seems to like numbers not greater than that. Anything beyond that number IE won’t understand. Here’s an example: http://blog.enrique-ramirez.com/wp-content/uploads/2007/08/css-columns-padding-revised.html

    Great article, just needs some more options. :)

  38. Darren

    September 2nd, 2009 at 9:49 PM

    @Enrique, I don’t see method #4 as ‘faking’ equal height columns at all. They are genuinely three columns of equal height with no hacks or javascript. You can see another explanation of the same technique here:

    http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks

  39. suffering

    September 16th, 2009 at 5:38 AM

    There is a good way for this:
    http://www.456bereastreet.com/lab/equal_height/

  40. Randall

    October 1st, 2009 at 7:36 PM

    I’ve been trying to find a solution for fixed width sidebars and variable width centre content (obviously with equal height background colour on all three columns). Can anyone suggest or provide a link to a solution?
    I’ve seen method 4 explained elsewhere but I believe the sidebar width will vary when the browser is resized.
    I’m a novice when it comes to CSS so apologies if I’ve missed something fundamental.
    Nicely written article, thanks.

  41. Ken

    October 21st, 2009 at 2:09 PM

    Great article. I just employed the java script option and it works great. Thanks for taking the time to write this.

  42. gaus surahman

    December 22nd, 2009 at 4:17 AM

    Good roundup.
    I implemented matthews method in my drupal themes, try this: drupal.org/project/plaingrail

    I know it needs more layout variations, but at least it’s the real world example and surely not for Dimitris, sorry :)

  43. colombopro

    December 29th, 2009 at 11:13 AM

    very informative. but how i can add borders to columns.
    javascript solution is the only thing that can be add borders to divs.

  44. Businessmess

    January 11th, 2010 at 7:53 AM

    I just looked at the wordpress theme ‘neoclassical’. This theme is nice but I want to do some tinkering to it. The thing is I can not find how it added borders to middle column. It has not used any borders in style.css.

  45. æ¶‚èšæ–‡

    January 14th, 2010 at 2:07 AM

    谢谢共享技术,让我们学习得更好。

  46. jason

    January 18th, 2010 at 8:19 PM

    good thinks

Join the Conversation!

Remember: Life's not all doom and gloom, so please keep it constructive. If we've made an error or missed something big, please let us know! Learning is revisions, after all.

CommentLuv is Enabled

 

Sponsors

Advertise on Build Internet!