Creating equal height columns with tables is easy. Of course we shouldn't use tables for layout. With CSS it's a little harder. If, for example, you create a three column layout by floating 3 DIVs within an overall container the result will probably look something like the following:
All's well and good except those pesky columns aren't the same height. It's tricky but we can fix this a number of ways without resorting to tables.
"Faux Columns"
The most commonly described method, "Faux Columns", works by applying a background image to an overall container. As the container will stretch to the height of the largest contained column, assuming a suitable clearing method is used, a vertically repeated background image representing the colour of each column will "fake" the effect of equal height columns.
JavaScript Solutions
Other solutions use JavaScript to adjust the height of the columns. I'm not keen on this approach.
Another Way
The third and final way which this post investigates uses pure CSS and doesn't require any background images, at least initially.
Taking the original example shown, we add a large bottom padding value to force the background of the shorter columns beyond the height of the longest column of content. The size of this padding is totally arbitrary. We just need to make sure it's enough to take account of the difference in content between columns. This gives us the following:
Next we trick the browser into thinking the columns are still only as high as the content they contain by applying an equal sized but negative bottom margin. Finally we add a rule to the container to hide the overflow created by the padding value. The result, 3 equal height columns.
But what if we want to add borders to the columns? Unfortunately, things become slightly more complicated. We start by adding some spacing between the columns. A right margin handles this nicely. Next we add a border rule to each column. This ought to be enough but unfortunately the oversized padding we added previously pushes the bottom border out of view.
To solve this we need to "fake" the bottom border using a background image applied to the main container and positioned bottom, centre. We'll also need to float the container or specify a width to force it to shrink wrap the columns and therefore ensure correct positioning of the background image. Internet Explorer only works if we also float the inner container.
We won't see the background if we apply it and the overflow hiding rule to the same container so we'll have to create an inner container and move the overflow rule to that. Finally we need to add a 1 pixel (or value corresponding to the border width required) bottom padding to the outer container to provide space for the background image to show through. We have now achieved equal height columns with borders applied.
Finally we can make the columns elastic by specifying the column widths in ems rather than pixels. To keep this example simple I've only included two columns.
Notes:
- I've tested the various examples described above in Firefox 1.5, Safari 2, Opera 9 and Internet Explorer 6.
- The third technique described here was, I think, first written about on Position is Everything in an article entitled One True Layout. I'd highly recommend checking it out also.
- Thanks to Andrew Phillipo, a Yahoo! colleague, for suggesting the use of a background image to solve the bottom border problem.
Great roundup, thanks!
so, instead of using faux coloumns, which works great, i should use some crazy css to get equal height columns?
@david - "Faux Columns" could be problematic if your columns need to be elastic or youn want to create a set of equal height boxes with borders. You also save an HTTP request with this method. That said, I'm just presenting the options - obviously it makes sense to use whichever method you feel most comfortable with.
I'm using Debian Sarge which still comes with Firefox 1.04 (with security fixes) and the third column's content appears below the first two as one paragraph as large as the browser window.
Very helpful, Thanks
Chris Williams did something similar a few months ago which also allowed for fluid column widths - but the CSS might be a little crazy!
http://www.chrisjwilliams.co.uk/article/Towering-Thrash-Box-Inferno
Edited to link URLs.
Amazing article! I didn't need it yet, but I'm sure that I'll...
Very smart, bravo.
I'd say this method is an alternative to faux columns, but doesn't replace it.
Or you could just use a simple table. I agree that CSS is great and should be used as much as possible, but not in scenarios where it's use is a great disadvantage. Isn't one of the philosophies of good web design avoiding bloat? I could write a convoluted code that relies on abuses and glitches to get CSS colums to work or I could keep it simple.
I use a design priority. Use CSS first, then Tables, then CSS:absolute positioning, then javascript, then flash if appropriate.
Don't handicap yourself to get things working in CSS. Do what works best and most efficiently. That's web design philosophy.
This is a simple re-hashing of the Equal Height Columns portion of "In search of the One True Layout" on Position is Everything:
http://www.positioniseverything.net/.../print
There are several issues that you need to be aware of when using this technique which are documented here:
http://www.positioniseverything.net/.../equalheightproblems
Edited to link URLs.
...or you could apply display: table; for your containing div and then add display: table-cell; on your column divs. it works in newer browsers. it's easy and it's dynamic; alter the contents of your columns realtime and the columns will still be balanced.
only real minus (besides bad backward compatibility) is margins for columns will be ignored (much like margin on td elements).
nicely done - thanks.
That is very nice.
A "simple re-hashing" of "In search of the One True Layout" on Position is Everything, or a simplified version? I'd say the latter, and what a great article this blog post is because of that.
Nicely written and very helpful. What I like about this article is that it gives me just enough information but doesn't overwhelm with technical details that are initially quite tricky to grasp.
The perfect lead-in to the Position is Everything article.
Thanks a lot, Ed. I've just subscribed to your feed :-)
Firstly, the comments link on your main page takes me to the form to add a new comment, but I would like to read the existing comments first. I have to scroll up.
Secondly, interesting article. I've been battling with columns and CSS recently, and come to realise that there is a serious problem with using floats. As your examples show, when the browser window is narrowed, the columns drop down, ruining any design. (In one of your demos, the background colour of the right column even changes from light grey to dark!) Whereas if a table were used, the columns would always stay together. And it would be easy to colour the cells and have them all the same height. Is there a way to get round this dropped floats problem? Alas we can't use display:table as IE6 and 7 don't support it. All this CSS and hacks is way too complex for something that should be very simple.
Chris - I take your point about the comment link. I'll get this fixed.
The columns only drop down in these simple examples because I haven't specified a width for the container. If you enter a width you'll find this no longer happens.
Re the colours changing, I haven't seen this myself but I'll look into it and see if I can replicate.
Ian - I do agree that this is a simplified version that is a little easier to digest and does have some value in that respect. However, I also think that proper citing of sources is critical, especially for something that's so heavily based on an existing technique.
Besides the lack of attribution, one of the other problems with not citing this source is that there *are* some gotchas (especially the anchors problem) that are well documented in the original but not even mentioned here.
If this article had been subtitled "Simplified Equal Height Method from In search of the One True Layout" with a proper link (or even if there had been a mention and a link in a footer), I wouldn't have had any issue.
Regardless, I think there's some good information here and have added the site feed to my feed reader.
Mark - I wasn't actually aware of the One True Layout article on Position is Everything before posting this article. I certainly don't suggest anywhere that I came up with the idea. I'm simply interested in providing simple explanations of how to use useful techniques and in that respect I hope it's been helpful.
That said, I agree that linking to the article on Position is Everything provides useful extra info and so I've now done so in the notes section of my original post.
Hello
Nice info on the Equal Height Columns, I have been experimenting with the Mark Challoner way for some time now Full Demo with free standing borders Sorry not for IE, move over, click on body, wrapper
Full Demo Sorry not for IE, move over, klick on body , wrapper
Hi!
Unless I see an example with CSS, that has 3 columns, each one containing text (!), each one containing a custum background image (with y-repeat!), and each one of same hight (irrespective of the amount of content, in any of the 3 columns) {and working correctly in all modern browsers} I shall continue to use TABLES.
As far as I know, only tables can do it. PLEASE show me otherwise.
(For me: tables are the forgotten holy grail)
Here's a solution to the problem the anonymous reader was trying to solve.
Equal Height Columns with Custom Background Images
Switching from tables to CSS layout is about separating the layers. (HTML for describing content, CSS for presentational display, JavaScript for behaviour). Most importantly it's about a return to using HTML in the way it was originally intended to be used - for describing the semantics of your content and therefore making it more accessible to all.
Actually, the claim that tables shouldn't be used for layout is groundless. They are perfectly acceptable, as long as standard Web practices are observed. I agree, if so-called CSS-based layout approaches don't work, use what does work, as long no rules are broken. Besides, because tables can be styled with CSS, they can rightly be considered part of "CSS layout" despite what the "experts" might claim. After all, how is using a series of nested s styled (in order) "display:table," "display:table-row," and "display:table-cell" (all of which, I believe are necessary for proper display in Safari, and none of which is supported in IE6/7) than using , , and ? Until IE better supports CSS, table will be needed, unless you are willing to compromise your designs to avoid them.
Oops, I should have remembered that that content within angled brackets doesn't display, so "how is using a series of nested s styled (in order) 'display:table,' 'display:table-row,' and 'display:table-cell' (all of which, I believe are necessary for proper display in Safari, and none of which is supported in IE6/7) than using , , and ?" should read "how is using a series of <div>s styled (in order) 'display:table,' 'display:table-row,' and 'display:table-cell' (all of which, I believe are necessary for proper display in Safari, and none of which is supported in IE6/7) simpler than using <table>, <tr>, and <td>?"
Lawrence - Tables are designed for displaying tabular data only and semantically they only make sense in this context. If you use them for layout then you're adding confusion to the meaning to the content in the page.
<div>s on the other hand don't have any inherent semantic meaning. They're simply containers for other elements.
Styling <div>s with display:table, display:table-row and display:table-cell doesn't alter the semantics, only the presentation. I'm am curious though as to what situations you feel you would need to use these display properties in Safari.
i have table with 2 columns and 10 rows 4 div each one having 5 to 10 pharagrahs.. and i'm displaying each div using onclick with CSS ,
wat want is how to auto adjust the row height according to the each div height ...now i'm giving row height manually it is assign to all the div . i want the solution for this can you help me in this
I was using this method for quite a while until IE7 came out. It collapses all the column down, a real pain in ass. I use the JS solution when I have to, but overall I try to design w/o equal height columns. You can also use a real fat border with negative margin.
I agree with several of the above posters re: tables. At this point the support for CSS in current browsers isn't consistent.
What is "it" all about? Making web pages that everyone can see as intended, or using CSS *entirely* so that we can say we did. What happens to all that broken CSS when browsers get updated and change how they deal with the mistakes? There's a reason they're called "hacks."
I think too many people are stuck in the "css or die" mentality, leading them to write web code that is just as bad as the table-ridden pages they bitch about.
And yes, I am fully aware of the benefits of DIVs over tables re: rendering and other specifics.
Nice post! Very helpfull solution.
hi! just stumbled across your post on google.. Thank you so much! I have been trying to do something similar for months!
Any suggestions for making this work under IE7?
Hello, there, Ed!
Just after making my brief post about making this work in IE7, I found a solution and thought I'd share it, here.
I did, indeed, have both of my equal-height columns set with the negative margin-bottom and positive padding-bottom (3000px, in my case) as well as making the enclosing div equal to a height of 100% (as well as both the HTML and BODY elements). The site worked fine under FireFox and IE6 (and less).
There was, however, a surrounding div between BODY and the content div.
What I needed to do was apply the 100% height to that div as well PLUS add the margin-bottom and padding-bottom lines. To target IE7, then, I used conditional comments:
I hope you find this helps!
This should have appeared in my previous post; stupid me, I forgot it was a comment...
<!--[if IE 7]> <style type="text/css" media="all"> #roxio_framework { height:100%; margin-bottom:-3000px; padding-bottom:3000px; } </style> <![endif]-->
David - thanks for taking the time to post your findings.
This technique you're using with padding and negative margins reminds a lot of how I solved a certain issue in the project I'm currently working on. When I found that solution I also found a accessibility/usability issue involved in using this technique - which hasn't been mentioned?
The user can not interact with the stuff below the equal height columns. This means they can't select the text, click on links, etc.
There is a easy way of solving this though, just add a z-index to the content below the equal hight columns.
Very clever, thank you.
Hi. I did find this article very well written and I do find it amazing what people come up with to make CSS do what it doesn't normally. However, for this latter reason I, too, have joined the side that says "why CSS at all cost?". The primary argument for using CSS for layout rather than HTML is to stay true to what they are meant to do. But if CSS is incapable (or not as capable) of achieving some things, then does that really mean it should be bent, twisted and poked with hot iron to give us the impression that it is capable? Isn't that what we did with HTML, but without the sleepless nights? I haven't used tables for layout for quite some time now... but man, there have been times!!! I will continue to use CSS only, because I do know it is the way forward and when it works it's SWEET! However, I do spend a lot of time searching for the neatest (and hopefully future-proof) solution for the trickier tasks I encounter.
Any chance you could try incorporating the fix for IE7 into your last example. I have not hand any luck so far.
Brett - I'll take a look.
content1
content2
and this
Hi Guys,
very good tutorial about equal height problems in CSS! BUT there is still one thing you can not do with this 'hack'. I am going to write my page partly in TABLES, because of this probeblem. Maybe someone knows a way? THE PROBLEM: 3 colloms next to each other with a background-image wich is positioned in the bottom of the three colloms. This is not possible, because it wil dissapair?
Ciao
I forgot to say something in my comment above.
I read about designers who were designing things differently because of the lacks css. If CSS is restricting design creativity, why should we use it? I was happy with tables, because i could make anything what came up in to my design programm. With al these CSS hacks it is not clear at all. And ofcourse, my comment above show the one of the lacks where I am talking about.
Anyone who has the 'restricions' with designing?
The overflow:hidden does not work in Netscape! Is there a solution for this?
Ciao - I'd actually argue that more complex designs are possible using CSS based layout than with tables. Just because one can come up with a design in Photoshop doesn't make it suitable or appropriate for the web. I think a large number of the problems people face comes down to trying to bend print designs to fit the web. By doing so one is completely misunderstanding the medium.
Carole - Which version of Netscape are you having problems in?
Carole is correct. The overflow:hidden does not work Netscape since it began using Firefox code up through version 8 since they were built on the Firefox 1.0 code base. Thus, it won't work on Firefox 1.0 either. It will work on starting with Firefox 1.5, but Netscape didn't change from the 1.0 engine until the recently released Netscape 9, which is based on the Firefox 2.0 engine.
There may be a way to work around the problem however. I learned about the problem after removing a javascript slide show from the page. With the slide show in there, it works fine, even in Netscape. With it removed, and my CSS buttons still in place, when I hit refresh it doesn't work, but when I click a button or resize the page, overflow:hidden immediately works. That is not true of a simple example where it never works. I have zoom:1 set to fix and IE refresh problem, but that does not fix this problem. I still do't have a concrete answer for the early Firefox code base. If anyone else does, I'd appreciate hearing about it.
Does this work in IE7?
Jen - yes works fine in IE 7.
Jack, I don't think anyone has an answer for the early Firefox code base :). It's almost like watching people who don't understand binary when they laugh at 1101001 and try to act like they actually understand the joke. I can see the point to everything here but honestly, and nobody shoot me please...CSS and I...well, we just don't mix and there's nothing anyone can do to change that. Even with simple codes and stuff. You know what I mean? I prefer layers and switching layers to tables and tables to layers. I feel it's a more basic and understandable approach. And even though it can cause some problems, I feel that I'm good enough at what I do to keep at least 90% of those problems from occurring. Doesn't anyone agree with me? I mean seriously. What’s the point of putting yourself through CSS if you really don’t have to?
Great post: You just saved my day! :)
Great post! As a teacher I gave this as an exercise to my students after our lesson in CSS. Do you also have something related to making collapsible cells for tables using CSS?
#3 worked like a charm, thanks for the tip.
Aaron
Man, I cannot thank you enough. With the countless designs of mine this has been the main problem and now it's solved!
This is a great solution, thanks again!
Good info - I had to have the overflow 'visible' in my main container 'div' and using your negative margin '-1000px'with the padding '1000px' in my left and right colum 'div' worked just like i need it to ...
/*MY CSS ----------ITALA-----------------*/
div.maincontainer /* This is the main container that holds the head section, the right & left col and footer */ { width:750px; height:100%; margin:0px 0px 0px 0px; background-color:#FFFFFF; margin:0px 0px 0px 0px; text-align:Left; overflow:visible; }
div.head /* This is the header with an image as a background graphic*/ { width:750px; height:100px; background-color:#ED8000; color:#FFFFFF; background-image:url('images\weekly-preview-hdr2.jpg'); background-repeat: no-repeat; }
div.r-col-container /* This is right col container */ { float:right; width:440px; height:auto; background-color:#FFFFFF; padding:0px; font-size:15px; margin:0px 0px 0px -300px; margin-bottom: -1000px; padding-bottom: 1000px; }
div.l-col-container /* This is left col container */ { float:left; width:300px; height:auto; border-right: 1px solid #CDCDCD; background-color:#EFEFEF; padding:0px; font-size:15px; margin-bottom: -1000px; padding-bottom: 1000px; }
div.footer /* This is the footer */ { width:750px; height:75px; background-color:#CDCDCD; color:#000000; border-top:solid #DCDCDC; border-bottom:double #DCDCDC; font-size:11px; }
Thanks for your help
Thanks, i was desperately looking for that info!, great article covering some points I really needed, some good usability info for.
Check out 2 equal height columns layout generator using columns swapping technique: http://2columns.net
Ed Eliot,
I am a newbie in webdesign and html, after reading your tutorial on this post, it did make me understand more on how to create a nice css layout. I like most is "Equal Height Columns with Custom Background Images", which i can include a background image on my design. Thanks!
Pawel,
Your layout generator is cool, at least for me, it let me create two column with ease.
Thanks for stuff.I was looking at the material over a large amount of time
Thanks! Saved me hours of effort!
Very good. Will be very handy on my next project!
Great tutorial for newbie like me, it is easy for a starter like me to understand and read! Keep up the great work and thanks for it.
Hi Ed, I've managed to get equal height columns in a different, simple way and it uses no CSS hacks. Here are three examples:
3 column liquid layout in pixels
3 column liquid layout in ems
3 column liquid layout in percent
Good article Edward! I'm a rookie - your site let me learn more. Thanks! Przewozy Autokarowe
I read about designers who were designing things differently because of the lacks css.
If CSS is restricting design creativity, why should we use it? I was happy with tables, because i could make anything what came up in to my design programm. With al these CSS hacks it is not clear at all. And ofcourse, my comment above show the one of the lacks where I am talking about.
life-saver! very thorough explanation...and doesnt leave much out!
When I took up a short course on web design, CSS was the very basic lesson I learned. But when it comes to practical web design, we were told: 1. If possible, avoid using tables when designing a web site 2. Never use CSS in creating tables. But my question was – What about if you’re left with no choice but to use tables and your client requires the use of CSS?
Thanks for sharing this information to us? This is truly helpful. You really made it easy for us.
not very useful
if the right colum have a lot of information to show (so a big height) the left column will not have the same height.
You did not solve the probleme at all...
What i love about this post.... quote "Creating equal height columns with tables is easy. Of course we shouldn't use tables for layout."
So there is a perfectly easy way of doing something but we shouldnt use it.... That's so typical of this industry...i've been in IT over 15 years now... Having just created a full blown flash site to avoid having to mess with this rubbish i know found out the google wont index it...great. The likes of the W3C and google would like you to create all your sites like them or wikipedia...of course you wont sell much that way. Perhaps we should all go back to green screens???
One thing i do know for certain... i wish i'd become a brick layer.
Sorry for the rant...know its not constructive.
ps....view the source on this site www.gamercize.net
it's nothing to do with me but its stuffed with tables and displays ok.
But i'm sure someone will have an opinion on how it breaks some standard or something
Any chance you could try incorporating the fix for IE7 into your last example. I have not hand any luck so far.
Thanks for very interesting article.
I see a lot of comments from posters that do not understand why we try to avoid using tables for lay-out. The explanations given are too abstract I think, so here's my try to an answer.
As I see it, a dynamic website consists of 4 different elements: 1) Server-side code (that generates HTML) 2) HTML (usually generated by server-side code) 3) CSS (usually static files) 4) Javascript (usually static files)
The problem with using a table for lay-out is that in order to change the design, people would have to change the code (templates) on the webserver to change the generated HTML. There exist many different systems for generating HTML, such as PHP, Pearl, Python, ASP, JSP, CGI etc etc.
Designers don't know all these systems. But they all know CSS (the good ones :-)). If we could generate such HTML that it's structure would never have to change just to change the design, we could just point designers to a demo website and say to them: "Make this site look like the new design by editing this CSS file". Designers can work on their local system with a few pages they saved to their machine and when they would be done we'd just swap the old CSS with their version and presto, done!
The designers and system administrators wouldn't even need us programmers to change the design. They can do it themselves. That's almost impossible with table based design.
Just have a look at http://www.csszengarden.com/ for a demonstration of what can be achieved. The site has hundreds of different designs that can be cycled through live, and the HTML stays the same, except for a stylesheet include.
Last but not least, with stylesheets you can serve different user agents different design by supplying multiple stylesheets and giving them a media attribute: media="print", media="screen,tv" etc. But when the main design is in tables, this totally messes things up because tables are difficult to style from CSS making it hard to do things like having the header, footer and navigation disappear from the print version of the page.
This column-height thing is just a short-term problem with CSS that will be fixed in the coming years (it's fixed in IE8 for example) and that's what the CSS design guys promoting table-less designs are aiming for. If you want to build a specific website and don't care about print, tv or mobiles, by all means use tables. But some of us are working on CMS software that generates HTML and we are interested in outputting HTML now that will work (with all modern devices and features) for years to come. Forward-compatibility is what we are looking for.
Thanks very Much!!!
Yes, avoid tables if you can. Sometimes, you just can't. I find it absolutely amazing there's no easy way to stretch a column in CSS. Who's coming up with these specs? Broken and useless.
Something like "height: parent;" So it will stretch to fit the container element. It could be so easy - this is a complete FAIL.
I am still using tables for my 3-column layouts and after reading this article, I am going to stick with tables! What's the point of using CSS if I still need to do all these contortions? The designers of CSS were somewhat short-sghted, I must say.
Thanks much, I had used the bottom padding and -ve margin technique, for the bottom border instead of using the image I used a 1px height div with exactly the same size, margin and paddings of the above columns