The Matching Columns Script Video Tutorial: Matching CSS div Heights
One of the fundamental problems people have with CSS page-level layout is matching CSS div heights. Others might call this ‘matching column heights’ in web pages.
In this article/video (see below,) we are going to solve this problem using a lesser known JavaScript method: the Matching Columns Script.
Let’s start out by checking out a diagram that illustrates the problem:

People have come out with different solutions including the ‘Faux columns’ hack: using a vertically tiled background image to create the illusion of a column.
The ‘Faux columns’ hack/trick works, but it does have some limitations:
- You have to mess around with background images when creating the fake/faux columns effect – there is even more mucking about when you have liquid layouts.
- You won’t be able to use CSS border styling (on your div’s that create the columns) because it would reveal the hack.
THE BETTER WAY TO HANDLE THIS PROBLEM: DOM SCRIPTING (JavaScript)
JavaScript (sometimes called ECMA script,) is the programming language built into all the browsers that allow geeks/nerds, to have practically total control over how things appear in a web page – it’s very powerful.
Note: DOM scripting (the term,) is a quick way to describe using JavaScript to control a web page’s structure. If this makes no sense, don’t worry about it as you need no programming knowledge to use the technique that is covered here.
WHY IS THE JAVASCRIPT METHOD BETTER?
You are better off with the JavaScript method (rather than the ‘Faux columns’ hack, ) because:
- Once it is applied, you don’t have to worry about it as it automatically adjust itself to change with your page(s).
- It is much easier/faster to apply than the ‘Faux columns’ hack.
GETTING STARTED
Attached with this article you will find the files you need to apply the script:
- The Javascipt file.
- The CSS document.
- A sample web page that puts it altogether.
Now it’s time to watch the video to learn how to use it.
CONCLUSION
There is one downside to this technique:
It won’t work if people have JavaScript turned off. Fortunately, the vast majority of people out there have it on. Last time I checked my own stats, nobody had JavaScript disabled.
That said, though it looks a lot better when your columns heights match, I would not consider it mission-critical to a website. That is to say; people will still be able to use the website, so I am willing to accept that for some rare (paranoid) individuals, the columns will not match.


Hey,
I have found an issue with this script. I have attempted to add an onload event to the tag. Once there is an onload event the columns fail to work. For reference, I was using the google maps API (And it requires a body onload function)..
No clue why this occurs. Without the onload event it works perfectly. This also occurs with any onload event.. Not GMAPS related
@Ryan,
It is not clear to me: are you trying to call both function on the onload event?
Can I see the way you are calling them?
Hey there,
Im not trying to call the javascript via body onload. I’m loading it the standard way ( )
The problem is that when I add an ‘onload’ event to the body tag for something else, for some reason it interferes with the matching columns and then fails to work
Standard way:
Ryan, Stefan
I am experiencing the same problem with having an onload call in the body element.
Reason its there is I have a form, and for usability I am using the onload call to place the cursor into the first form field.
As soon as I remove the onload function from the body element the columns match up like butter.
Is there a way for the matching_columns script to work in harmony with a body onload?
thanks
Someone has submitted a new version of the script – the details are in the code:
/*
Derived from a script by Alejandro Gervasio.
Modified to work in FireFox by Stefan Mischook for Killersites.com
Modified to work with multiple class groups also with elements with multiple class names
by Jonathan del Mar (dec-14-2006)
How it works: just apply the CSS class of ‘column’ to your pages’ main columns.
to work with different classes
add
by Jonathan del Mar
by default the script will call
matchColumns();
and the default class_name is ‘column’
(see the bottom of this script)
by Jonathan del Mar
*/
matchColumns=function(my_class){
var divs,contDivs,maxHeight,divHeight,d;
// get all
divs=document.getElementsByTagName(‘div’);
contDivs=[];
// initialize maximum height value
maxHeight=0;
if (!my_class) {
my_class = ‘column’;
}
my_regex = new RegExp(‘(.* |^)’ + my_class + ‘( .*|$)’);
// iterate over all
for(var i=0;i
elements with class attribute ‘container’
element
elements
contDivs[i].style.height=maxHeight + "px";
// make collection with
//if(/\bcolumn\b/.test(divs[i].className)){
// modified by Jonathan del Mar to match ‘column’ in multiple classes
if(my_regex.test(divs[i].className)){
d=divs[i];
contDivs[contDivs.length]=d;
// determine height for
if(d.offsetHeight){
divHeight=d.offsetHeight;
}
else if(d.style.pixelHeight){
divHeight=d.style.pixelHeight;
}
// calculate maximum height
maxHeight=Math.max(maxHeight,divHeight);
}
}
// assign maximum height value to all of container
for(var i=0;i
}
}
// Runs the script when page loads
window.onload=function(){
if(document.getElementsByTagName){
matchColumns();
matchColumns(columns[i]);
if (columns) {
for(var i=0;i
}
}
}
}
I used your tutorial and I am very impressed by the video as well as the end result; much better solution to others I have come across while searching for a solution to this problem.
I have one issue however … although my left hand div now has extended in length, there is a 1 pixel gap between it and the footer image. Any suggestions on why this may be?
Thanks for your help
Great stuff! I put it in the new wordpress theme I’m building, and theres a slight problem: now it makes the colums way too high, resulting in lots of empty space between posts.
how can I fix this? The CSS for the two columns is this:
#flare {
float:left;
width:142px;
text-align:left;
font-size:11px;
color:#FFFFFF;
font-family:helvetica;
color:#FFFFFF;
padding: 10px 4px 0px 10px;
line-height:130%;
background: #2D2D2D;
}
#post {
width:530px;
text-align:left;
margin-left:156px;
font-family: helvetica;
font-size: 10pt;
line-height: 130%;
padding: 6px;
font-family:helvetica;
color:#000000;
}
@Frances,
I would have to see your layout, but keep in mind that the script simply compare the two or more
So I would guess that the script is just revealing some other aspect of your layout that was not apparent before you applied it.
I’m glad you liked it.
Stefan
I’ve put a screenshot of what happens at http://www.trythisonforsize.net/downloads/screenshot.png
Hope you can help me out…
I think i know what happens: it makes every post the size of the longest one; this is probably not going to work for a blog right?
@Rik,
This has to do with the CSS code and the structure of the blog template and not whether or not it is a blog.
You would have to dig into the template code to work it out.
BTW: did you design the templates?
Hi Stefan,
thanks a lot for your script, it really saved me a lot of time.
Unfortunately I discovered a small problem when i was working on a layout with 3 divs where two of them have a 1px border.
The div without border is missing 2px…as far as I can see the borders are drawn as outlines!
I tried to solve this problem with additional CSS styles but I couldnt find any proper solution.
Is there any way to expand your script with an additional class e.g.:
.column_no_border = maxHeight +2px or .column_border = maxHeight -2px ?
Maybe you could put me in the right direction (because i dont have any JS skills
Thanks in advance
Chris
Hi,
I haven’t looked at the script in a while. But I suspect that what you want is possible.
Sorry I haven’t the time to look into now, but maybe later.
Stefan
Goos script, thnx 4 sharing it. I’ve noticed when implementing it that it is very slow 2 apply onload. I’ll have 2 hover over some javascripted links in order 2 get it going! Do u have any idea y would that happen?
I haven’t noticed much of a speed issue myself … but I haven’t tested every possible layout.
That said, I would suggest creating a basic 2-3 column page and test the script as your gradually add complexity to your page layout.
.. Hopefully this process will help you identify what is slowing things down.
Stefan
[...] I decided to create another blog post to make it easier to find the updated version of the important matching columns script – it was buried in the originals article’s comments. [...]
like the script… but it doesn’t work with multi-column liquid layouts as far as i can tell…
seems to only work on reload for me. is there any way of adding an on_resize hook?
@Rob,
I haven’t tested all possible layouts … that said, it should work whether it be liquid or not … the logic of the programming is related to the heights of the targeted
I would take a closer a closer look at how you apply it.
PS: we may wan’t to check out webshapes.org for a growing collection of open source templates.
Stef
Hi Stefan.
Great script, except…..
I have used it on a 3 column layout but have found when the centre “content” column has dynamic content (ie generated by php) the column height stops at the height of the tallest other column (in this case the menu). When I populate the centre colum with regular html it works fine.
Could you offer any advice please
Regards.
@Dylan,
My guess is that it is a timing issue where the script is being fired before the content has been filled in completely.
.. This is a hard one to explain (and might not make any sense,) but what it comes down to (in theory) is that the script needs to be delayed a second or two before firing
… perhaps create a function that calls setTimeout() that calls the columns script.
?
Another option is to change the order that which the columns appear in the page’s code – make sure the dynamic column comes in first.
Hope that helps,
Stefan
Stefan,
The script worked fine in IE 7 and Firefox, but I had a javascript problem with IE 6 (same problem, tested on 2 browsers). The problem was that the div Height was returning NaN. This could be because of my goofed up styles, but I was able to fix it by adding the following:
if (isNaN(maxHeight)) {
// GRRRR IE 6 behaving badly
if (pageName==’somepage’) {
maxHeight=3730;
}else if (pageName==’anotherpage’) {
maxHeight=825;
}else {
maxHeight=0;
alert (‘missed one: ‘ + pageName);
}
}
The pageName is sent in using the form’s onload event like this:
where doLoad calls the matchColumns(pageName):
function doLoad(ButtonName) {
setButtonBackground(ButtonName) ;
if(document.getElementsByTagName){
matchColumns(ButtonName);
}
}
To get it to work, I redefined matchColumns like this:
matchColumns=function(pageName){
….
…
}
Kludged, but working.
Thanks for the post, by the way.
Cheers,
Steve
@Steve,
Thanks for sharing your modification with us.
Stefan
Thanks for this script, it’s great!
After reading the complete comments, I couldn’t find the source of the updated script to manage multiple calling for different set of heights (either the code was badly rendered in the replies of the link Stefan provided is empty, and I needed to call it 4 times) so I made some small updates and thought I’d share it with everyone.
From the original script (available to download), I replaced 2 lines :
replaced the function first line
matchColumns=function(){
by
function matchColumns(classname){
and the IF
if(/\bcolumn\b/.test(divs[i].className)){
by
if(new RegExp(“\\b” + classname + “\\b”).test(divs[i].className)){
So now I can call the same function and passing the class name in parameter like this :
matchColumns(‘column’); // class=column
matchColumns(‘maincolumn’); // class=maincolumn
Enjoy
Michel
I have applied this script to one test page, but it doesn’t seem to work. Any idea why? The test page is http://www.presentationsdirect.com/Laminators/GBC-Laminators_test.asp.
If it was working correctly, the divLeftColumn is supposed to extend down to the length of the divContent and divLeftColumn would have a gray background.
Michel (or anyone),
I dont understand how to call the javascript function from within html.
I have 2 different situations on one page where Id like to use this script but only one will work. I tried creating two different js files )renamed and called to each, but only one will work. Please help! Thanks so much
Dear Stefan,
Many thanks for this script. It works perfectly for me. However I have a question. Currently the function matchColumn is triggered by windows.onload. Is there a possibility that I also can trigger the matchColumn function when a browser window is resized.
I’ve tried:
windows.onresize=function() {
if {
if(document.getElementsByTagName){
matchColumns();
}
}
However that doesn’t seem to work. Any idea how I could fix this? Many thanks for your response!
Regards,
Tom
This script works well, but when I try to add a slideshow script to my page, the matching columns script stops working. The slideshow is triggered with onload in the body tag. Any idea why this is happening?
Thanks,
Debbie
Hey Stepan,
I have used your script multiple times without any problem. For some reason I can’t seem to figure this one out. Currently designing a 2 col layout, header, content, nav, footer. content and nav positioned relative with the class=”column” assigned to each div. the script to call the js is in my code. the js is on the server ect. any feedback would be greatly appreciated.
Just in case anyone wants to know i figured out my problem. as a looked into how the matching_columns.js worked i noticed on line 67 if has a onload function. that got me curious b/c I was using this piece of code to do the swap image restore function. i removed this and just had my tage and my columns matched perfectly.
i just wanted to drop you a line and say thank you so much for publishing this script. it worked perfectly with the site i’m working on, what a relief! thanks so much.
Veronica,
Glad to hear you found it useful.
When I ran into the columns problem, I knew that I had to get a fix out there for everyone.
Stefan
I’m having MUCH troubles trying to get the cols to match. I believe that I’ve got the proper files/code inserted as is needed, but the dang left hand side gold coloured will NOT stretch enough to match the main content .
PLUS, I also used the same class on the overall so that the footer will always drop down to the bottom of the overall content and that 1px black border will always be outside all content….
What am I doing wrong?
Test page is at — http://www.kkt-testserver.com/Lions/index.html
Can NOT get this straight!!!! Dang it!
Jim
Have a fairly hacked up site-but I was able to get it to work on FF and IE7, ie6 not so much the left drops down about 200px lower than it should and doesn’t fill. What am I doing wrong?
@Jenga,
It is very hard to help without code samples … That said, please post your question to the forum so other people can get involced:
http://www.killersites.com/forum/
Stefan
Hello everyone. It’s a great script. I have a question. I try like Michel say “multiple calling for different set of heights” with the updates
“replaced the function first line
matchColumns=function(){
by
function matchColumns(classname){
and the IF
if(/\bcolumn\b/.test(divs[i].className)){
by
if(new RegExp(”\\b” + classname + “\\b”).test(divs[i].className)){
So now I can call the same function and passing the class name in parameter like this :
matchColumns(’column’); // class=column
matchColumns(’maincolumn’); // class=maincolumn
”
But it doesn’t work. I’m sorry, I’m pretty new in this, so I apologize if my question sounds stupid. Here is a little example that I’ve try to do.
http://smile.sellinet.net/col/tmp_NEW.html
If anyone can help, I would be grateful. Excuse me, for my bad English.
Thanks for the hack – it saved my butt on a project for work! Good vid too.
Excellent tutorial! Worked perfectly for me. Thanks!
I don’t see how this works Stefan. If you would give the navigation background a different color in your example, maybe some of us newbies could see the columns being matched up. However, both have no background (white default).
I used your files and only changed the following:
1) changed the color of the navigation column (in the style sheet) to color: #CC0000. (so I could possibly see the difference).
2) Decreased the quantity of text in DIV “CenterDoc” to only 2 paragraphs of data.
I have posted the results for viewing. The navigation column continues down to infinity, where the CenterDoc column terminates a little after mid page going down. Am I missing something here? Shouldn’t the left navigation menu (in red) cutoff at the same point where the text in the CenterDoc column ends?
Please any advice appreciated.
Stefan,
I stand corrected. It seems to be working in IE, but in FF the left navigation column (red) just continues down to infinity. So, perhaps FF is not picking up the Java Script?
Any ideas?
Thanks
unfortunately, I have no ideas for now
i don’t know what i am doing wrong but it’s somehow not working under IE6.checked and rechecked my codes still nothing.i am using a w3c css template.
any idea on how to fix it? thank you.
Absolutely the best! Thanks. This made my life sooooo simple. I am moving from all html to mostly CSS and you saved me gobbs of work!
Hi, I am trying to incorporate your script into Wordpress, as the faux columns technique simply won’t work with my template. I have copied the script src line into my header.php template, and have applied class=”column” to the div ids, but it does not seem to work.
(Currently I am only testing in Mac/Firefox 2.0, but will test other browsers/platforms once I get this aspect of the site sorted out).
Any suggestions on what I might be doing wrong?
Hi Michelle,
It is hard to diagnose without seeing all the code. But let me think …
Be sure that you are loading the .js file properly … check your paths.
Stefan
Hi Stefan,
Here is the header.php code. I tried renaming the script path to the full url, but that didn’t seem to help.
<meta http-equiv=”Content-Type” content=”; charset=” />
<meta name=”generator” content=”WordPress ” />
<link rel=”stylesheet” href=”" type=”text/css” media=”screen” />
<link rel=”alternate” type=”application/rss+xml” title=”RSS 2.0″ href=”" />
<link rel=”alternate” type=”text/xml” title=”RSS .92″ href=”" />
<link rel=”alternate” type=”application/atom+xml” title=”Atom 0.3″ href=”" />
<link rel=”pingback” href=”" />
<a href=”/” title=” “>
Sorry, that didn’t seem to work.
/*
<meta http-equiv=”Content-Type” content=”; charset=” />
<meta name=”generator” content=”WordPress ” />
<link rel=”stylesheet” href=”" type=”text/css” media=”screen” />
<link rel=”alternate” type=”application/rss+xml” title=”RSS 2.0″ href=”" />
<link rel=”alternate” type=”text/xml” title=”RSS .92″ href=”" />
<link rel=”alternate” type=”application/atom+xml” title=”Atom 0.3″ href=”" />
<link rel=”pingback” href=”" />
<a href=”/” title=” “>
*/
Apologies again. I obviously don’t know how to copy&paste code so it shows correctly in the post.
Stefan, I am so happy I can cry. Yes, perhaps I should get out more
I have made a very complicated template system for a CMS called Mambo and the last thing I needed to do was this. I didn’t think I’d ever manage. It is great! Everlasting gratitude from Tengu!