Really simple CSS trick for equal height columns

in Web Design Oct 11, 200943 comments

This tutorial describes a really simple CSS trick to implement a fake equal height columns effect using the CSS properties position:absolute and border. Before to proceed I suggest you to download my CSS 2 Visual Cheat Sheet for a practical reference guide to CSS 2 properties that can help you understand concepts illustrated in this post.

Image to have this situation: you have to implement a two column layout and you want the height of the sidebar column is equal to the height of the main content column. The following image illustrates our problem:

HTML structure

The first step is to define the HTML structure of our document. In this example I used a simple two columns layout like this:

<div id="wrapper">
<div id="maincontent">...</div>
<div id="sidebar">...</div>
</div>

#wrapper

The #wrapper layer will contain our two columns, #maincontent and #sidebar:

#wrapper{
margin:0 auto;
width:600px;
}

#maincontent

The #maincontent layer is the left column of the document that will contains the main content of the page (for example the text of posts). The following image illustrates the basic concept I used to implement this trick:


We have to add an extra border to the #maincontent layer (200px) above which will be placed the #sidebar. In this way we’ll have a fake background for the #sidebar, represented by the right border of the #maicontent column, that will have the same height of the #maincontent layer. Here is the CSS code:

#maincontent{
border-right:solid 200px #DFDFDF;
position:absolute;
width:400px;
}

#sidebar

Now we have to define the #sidebar using the following properties:


The width of the #sidebar is the same of the #maincontent right border width (200px) and the property margin-left is equal to the #maincontent layer width. Here is the CSS code:

#sidebar{
background:#DFDFDF;
margin-left:400px;
position:absolute;
width:200px;
}

In this way the height of the #sidebar column will seem the same of the #maincontent column height.

  • paul

    Thanks Antonio,
    great tutorial. have you tested it on different browsers?

    • Antonio Lupetti

      Not IE6.

  • Ethan

    Interesting solution. But it isn’t flexible and if the sidebar is longer than the main content then you’re kinda screwed…

    • Antonio Lupetti

      No, it works in both cases :)

  • nomi

    Pretty smart. :)

  • JoomlaWorks

    Kind of restrictive really, as you’re using the border color as the background of the sidebar element. But what if you’d want to have a background image repeating on the sidebar? Don’t get me wrong, your tut shows the possibilities of CSS but in this case and in my opinion, either use the faux columns technique with reverse bg colors or 3-4 lines of Mootools to make the blocks stretch to the height of the “tallest” one. ;)

    window.addEvent('domready', function(){
    // Equal block heights
    if($$('.commonClassForEachBlock')){
    var blocks = $$('.commonClassForEachBlock');
    var maxHeight = 0;
    blocks.each(function(item){
    maxHeight = Math.max(maxHeight, parseInt(item.getStyle('height')));
    });
    blocks.setStyle('height', maxHeight);
    }
    });
    • Antonio Lupetti

      If you’d want to have a background image repeating on the sidebar you can simply change the #maincontent margin-right property with padding-right and add a background image aligned to right in the #maincontent layer without using JavaScript!

  • tigo di

    I like your solution and i will test it in some sites but each case is a case.
    Good job! ;]

  • Husien Adel

    hmmmmmm , I will try it and see the Results
    any way thanks man :)

  • Amanda Fazani

    Thanks for writing this Antonio, it’s a fantastic idea which I will certainly experiment with =)

    • Antonio Lupetti

      Thanks Amanda :)

  • f055

    Interesting approach, but I think using “float” is simpler and better: http://f055.net/article/simple-yet-perfect-2-column-layout/

    • Steven

      That technique is the basic for 2 column layout and works if your content is on a same color background.

      Let’s say you have background-images in your columns and they need to be the same height… if column 1 is longer than column 2, column 2′s background will stop where the content stops.

      I’m not a fan of Antonio’s technique, but hell it works! I gotta give him that. That’s using your brain! :)

  • Daniel Kurdoghlian

    I wouldn’t call this a nice solution..
    Why not fixed height for wrapper and 100% for child elements?
    Or a small js(jquery, mootools, whatever-framework) which takes care of the height..

    I would not suggest people to use the border as a background color – don’t get me wrong tho.!

    • Antonio Lupetti

      I prefer don’t use JavaScript for this kind of thing. 100% height for child elements is another good solution.

  • sarimarton

    Ethan says:
    “Interesting solution. But it isn’t flexible and if the sidebar is longer than the main content then you’re kinda screwed…”

    Antonio Lupetti says:
    “No, it works in both cases :)”

    No it doesn’t. Have you actually tried it? Because I did. Here is what is see: http://martonsari.com/eqcolums

    Your only idea is that you can use a wide border as a background. Nothing more. (And why not an off-the-margin overflowed 100% height child box for that? It’s the same, just more semantic.)

    By the way, one can immediately see that it doesn’t work, as you’re using absolute positioned boxes. As absolute boxes cannot have an effect on containers, the information that they’re higher than the other box can’t be yield.

    So if you want a background for the main box, it doesn’t work if the sidebar is higher.

    • Antonio Lupetti

      But your example is different. You are using a different background for the main content column and in this case things are a little bit different.
      The #wrapper layer allows to center the two columns on the page: when you say “as absolute boxes cannot have an effect on containers” take a mind you have the same problem if you use float elements. In fact, in this case, you have to set the background of the #wrapper to the color of the #maincontent background and add a after the #sidebar to force the height of the #wrapper to the height of the longest element.

  • Hezi

    interesting solution . i’ll give it a try ;)

  • ilya

    Hey! Very, very crerative solution. SImple, not obvious. Brilliant!

  • sunny

    interesting. I’ve tried to find solutions for height stretch problem. Thank you for another interesting idea! I’ll try it.

  • DOM

    Here is another solution by Jeffrey Way from NettutsPlus
    http://blog.themeforest.net/screencasts/use-absolute-positioning-to-create-equal-columns/

  • Ali

    Interesting solution and nice idea.
    Thanks for sharing
    keep it on!

  • Web Designer

    wow, a very simple and a good solution

    thanks

  • ZSK

    Recently a faced a similar problem and I solved it in the below way. I know it’s not too elegant using a hard coded value for the padding-bottom, margin-bottom properties but giving a huge number to them will guarantee that they will work. The margin-bottom value must be the same as the padding-bottom by using negative sign in front of it. Actually this number will tell the maximum difference between the columns in pixels.

    And by using this solution either column will expand to the bottom of the other one irrelevant which one is the taller, background images can be used as well, and of course this is only css, no javascript needed.

    #wrapper{
    overflow: hidden;
    margin:0 auto;
    width:600px;
    }

    #maincontent, #sidebar{
    float: left;
    padding-bottom: 9999px;
    margin-bottom: -9999px;
    }

    #maincontent{
    background:#ccc;
    width:400px;
    }

    #sidebar{
    background:#DFDFDF;
    width:200px;
    }

    Cheers,
    ZSK

  • Abhinav

    Nice! Pretty similar to Faux columns!
    :)
    Thanks!

  • Zangui

    Simple and consistent. Normally I use the float property to put both layer side-by-syde. I’ve never use this way. I will pratice this.

    thanks

  • Derrick

    Great technique. Tested with different background colors and it worked.

    Tested on IE 6 and it worked.

    Nice and simple.

    Thanks.

    MD

  • Julien

    You make me love CSS !

  • Cephalopod

    Thanks so much for this.
    Column sizing can be such a pain and I am going to implement this right now.

  • Marco

    Quite interesting.. But, I think the faux-columns-technique is the way more practical solution for this ‘effect’.. Imagine, you want a 1px border between #maincontent and #sidebar – which is not uncommon..

  • FatboySammy

    Hi Antonio,

    Excellent piece of work. Thanks.

  • Robert

    Looks interesting. I will have to give it a shot and see how it works. Thanks for sharing.

  • Maninder Pal Singh

    Easy and effective solution to a tough and tricky problem.

    Thanks Antonio.

  • Kouba

    I added your blog to bookmarks. And i’ll read your articles more often!

  • mass tort attorney

    Smart…I will be trying this out.

  • Darrel

    This is where JS really helps. Yes, CSS is supposed to be for visuals and JS for interaction, but it’s so easy create equal heights with javascript (especially if you’re already using jQuery) that the CSS solutions quickly begin to seem quite ‘hacky’. Clever, sure, but still ‘hacky’.

  • istanbul

    thanks for easy and useful tip.

  • Ruana

    Nice trick. As before mentioned, it’s depending on the case which technique you’re using. I did experiment with this one and it’s not working in every case. Most of the time you’ll have two different background-colors/images, one for the sidebar and one for the main content. And you just can’t guarantee that the main content always stays longer than the sidebar – esp. if you’re working for a client.
    I love the trick from Nettuts. Everyone who didn’t check it out yet – highly recommended.

  • Pumpkin

    can it applied with sidebar border? and how if there are 3 columns and each column have its own background image?

  • Jim Joyce

    Thank you.
    That’s unbelievably simple.

  • Web Design Mauritius

    Great tutorial. I will try this solution out. Thanks for sharing.

  • Koh Chang

    At first I try Antonio’s CSS.
    It works correctly as I want.
    But when I add content in footer, I get footer content going to top.

    So I try ZSK’s CSS.
    I also works correctly when I add content in footer.

    I am not good in using CSS. So I cannot think by myself to solve problems.

    Thank you very much. Antonio Lupetti and ZSK.