After I wrote and published my last article on writing a function to equalize heights in jQuery, I realized that the function would probably make a really useful jQuery plugin. This is that plugin.
This is also my first attempt at a jQuery plugin, so I apologize in advance if I’ve done something painfully stupid (and painfully obvious) to any and all plugin veterans out there. Luckily, the functionality is extremely simple.
You can download the plugin here (right-click and save the link).
You can see a demo of the plugin here.
The plugin’s functionality is so simple because it’s designed to do only one thing: set all elements you specify to the same height.
This plugin is slightly more sophisticated than the function I wrote earlier this week. Instead of being stuck setting all your columns to the height of the tallest element, you can also (optionally) specify a minimum and maximum height you want the element to be.
For example:
$(".columns").equalHeights(100,300);
This would set all your elements to be at least 100px tall, but no more than 300px tall. If your tallest elements contain more than 300px worth of content, the containing element will still be resized, and a scroll bar will appear on the side of the element. If you only specify one number, that number will be treated like the minimum height, meaning all elements will be at least that number of pixels tall.
You can also nestle the function inside of a chain, to keep your code minimalistic:
$(".columns").equalHeights().css("color","blue");
Detailed Usage
For those not familiar with using jQuery plugins, here’s what you need to know.
- Load the jQuery library in your document’s head. That’ll look something like this:
- Load the equalHeights plugin the same way. Be sure the plugin comes after (i.e., below) the main jQuery script… the function relies on jQuery already being loaded:
<script language="javascript" type="text/javascript" src="jquery.js"></script> <script language="javascript" type="text/javascript" src="jquery.equalheights.js"></script>
- In order for the function to be able to calculate heights accurately, you’ll need to make sure it waits until the page is done loading before running. So wrap the function call (just like you should most all of your jQuery functions) in a $(docment).ready() function, like so:
$(document).ready(function() { $(".columns").equalHeights(100,300); });
<script language="javascript" type="text/javascript" src="jquery.js"></script>
And that’s about all there is to it!
Known Limitations
- Sometimes this script has trouble accurately calculating heights in Internet Explorer if you’re trying to find the height of an element that contains images that don’t have heights set. Unless the height has been specified, the script seems to assume a height of zero.
- If you resize the text in your browser window, the blocks will not resize automatically. In some browsers, you would be able to fix this by calling the script again on resize, with something like:
$(".columns").resize(function(){ $(".columns").equalHeights(); });However, I’m given to understand that this doesn’t work on Firefox, as the browser doesn’t report text resizes as a “real” resize. I’m currently not aware of a good workaround.
Worth Mentioning
I should point out that there is a similar jQuery plugin out there already called equalHeight which has similar functionality. However, that plugin requires significantly more code and the author warns that it doesn’t work in Internet Explorer. I feel my contribution, which is very small and cross-browser compatible, is thus still worthwhile.
Further, CSS Newbie reader Jared Mellentine posted a similar jQuery function in the comments of the previous Equal Heights article. His functionality is slightly different than mine (his looks specifically for child elements, whereas mine assumes you’re specifying the elements you want to resize directly), but he did give me the idea of adding additional functionality to my plugin. So thanks, Jared!



On December 10, 2008
8:11PM
Bryce said:
If only you had released this last week, you would’ve saved me a lot of heartache! Thankyou so much!
On December 11, 2008
2:40AM
CircleReader said:
Thanks for this code, Rob. Your demo seems to be working just fine in FF3.1b2!
On December 11, 2008
6:54AM
Crealup said:
If I have the experience to do the same thing using jQuery dimensions, give me one good reason why this is a better solution :)
On December 11, 2008
12:16PM
Marina said:
This is great. I found it by chance today that I was thinking how to go about solving this problem. Many thanks!
I had to change the scroll to visible though because for some reason when I set it to ‘make them all however the biggest box is’, the biggest box get a scrollbar.
On December 11, 2008
12:17PM
Sérgio Jardim said:
This is a nice plugin! Thanks a lot!
Cheers from Brazil.
On December 11, 2008
12:58PM
andi said:
great, thanks. this is really useful.
On December 11, 2008
2:39PM
Rob Glazebrook said:
Thanks for all the great responses, all. :)
On December 12, 2008
5:14AM
pSinke said:
Awesome, this will be very useful in this project I’m about to start on. Thanks a bunch.
On December 12, 2008
5:52PM
AlexD said:
Hello.
I have tried to use it, but since i am new to the Jquery thing how do i specify exactly WHICH element to equalize, for example if i have 5 boxes but only want 4 of them to be equlized/changed sizes/etc how can i do with this piece of Jquery code you wrote.
PS: i was using something very similar to this thing via normal javascript wihtout any libraries but it’s a lot longer given the fact that you have to type document.getElementById a lot of times.
Thanks, hope you’ll answer.
On December 13, 2008
11:41AM
Rob Glazebrook said:
Hi Alex,
What you need to do is give the four boxes you want to equalize the same class, and then apply the equalHeights function to just that class. So if you gave those for boxes a class of “resizeme”, your code would look something like this:
$(”.resizeme”).equalHeights();
Does that help? If you’re new to the idea of CSS classes, you can learn more about them here.
On December 13, 2008
12:21PM
Alexandru Dinulescu said:
Hello.
Thank you for your answer Rob, i have been doing webdevelopment for a couple of years but only now i am starting to get into the realm of JS. Your explanation was very clear and i appreciate you taking the time to respond.
Best wishes.
On December 15, 2008
12:06PM
Olivier G. said:
“If you resize the text in your browser window, the blocks will not resize automatically.” : it will if you use min-height instead of height (exept for IE) (but heights between blocks will become different).
On December 15, 2008
12:27PM
malsup said:
Rob,
You’re missing the ‘var’ keyword when declaring the ‘tallest’ variable. Other than that - looks good!
On December 17, 2008
6:08PM
Eugene Kulikov said:
Hello. Here’s the solution for text resize detection in A list apart article.
On December 19, 2008
12:56AM
krish said:
Hi Rob
This is great. I wonder how to make two columns of different width - for instance right col 600px width and left col width 120px - using this jqery plugin script. Can you help me please.
Thank you
Krish
On December 19, 2008
9:42AM
Rob Glazebrook said:
Hi Krish,
You would just use CSS to make the two columns different size. I would suggest giving the two columns different IDs, but the same class. For example:
<div id=”col1″ class=”column”></div>
<div id=”col2″ class=”column”></div>
That way you can still use jQuery to find your “column” class, but can make them look different according to their IDs.
On December 19, 2008
5:00PM
Dave said:
To trigger resize in Firefox, try something like this:
$(window).resize(function(){
$(”.columns”).trigger(”resize”);
});
Or you could call .equalHeights() from there directly.
On January 13, 2009
12:07PM
Paul Irish said:
I wrote this and it does the job in most cases:
$.fn.setAllToMaxHeight = function(){
return this.height( Math.max.apply(this, $.map( this , function(e){ return $(e).height() }) ) )
}
On January 14, 2009
11:02AM
mark sanders said:
Hmm….i’m currently seeing scrollbars (vertical and horizontal) in IE6.
they only disappear when I change the plugin so that overflow is hidden.
On January 14, 2009
11:12AM
Rob Glazebrook said:
Hi Mark, I’ve noticed that can sometimes happen in IE if the columns contain images that don’t have a specified width and height set. In most browsers, jQuery ends up receiving the computed height of the image. For some reason, however, IE doesn’t seem to send a computed height, but instead sends a height of zero… which results in shorter than necessary columns and therefore scrollbars.
My recommendation on this is to set the height of images whenever possible to avoid this problem.
On January 14, 2009
1:44PM
Jamie Krug said:
@Rob, thanks a bunch for this, very handy! Unfortunately my first implementation caused a vertical scrollbar to show up in Firefox (but fine in IE6/IE7). Who knows which CSS rule or quirk or whatever is causing this. I have height and width set on all images. Possibly related to relative font-size (em)? Anyway, I figured the quick fix for a non-JavaScript/CSS-guru such as myself is to simply set the overflow attribute to “visible” instead of auto (as you have it in your script). Or, I thought maybe just a couple pixels extra to the equalized height. So, here’s the revision of your script that I’m now using with success…
/**
* Revision: 1/14/2009, Jamie Krug
* Changed signature to accept one optional argument (options) as an associative array to better support more optional “arguments” in a more readable fashion.
* Added overflow option, to override default CSS declaration.
* Added addToHeight option, to optionally pad tallest height (can be used as a quick fix in quirky situations where a couple extra pixels will avoid overflow).
*
* Example 1: $(”.cols”).equalHeights();
* Example 2: $(”.cols”).equalHeights( { minHeight: 400 } );
* Example 3: $(”.cols”).equalHeights( { minHeight: 100, maxHeight: 300 } );
* Example 4: $(”.cols”).equalHeights( { overflow: ‘visible’ } );
* Example 5: $(”.cols”).equalHeights( { addToHeight: 3 } );
*
*/
(function($) {
$.fn.equalHeights = function(optionsArg) {
var options = { minHeight: 0, overflow: ‘auto’, addToHeight: 0 };
for (var n in arguments[0]) { options[n] = arguments[0][n]; }
var tallest = options.minHeight;
this.each(function() {
if($(this).height() > tallest) {
tallest = $(this).height();
}
});
if((options.maxHeight) && tallest > options.maxHeight) tallest = options.maxHeight;
tallest = tallest + options.addToHeight;
return this.each(function() {
$(this).height(tallest).css(”overflow”,options.overflow);
});
}
})(jQuery);
On January 18, 2009
12:40PM
Patrick Elward said:
So far, this thing ROCKS! I love it. I’m new to jquery and tried to combine your code with another jquery plug in, and am having some issues with it.
You can see it here: http://www.awbworld.com/rounded3.php
On IE, it fails to ‘move’ the border to the bottom.
on FF, it looks fine.
Any thoughts?
The source for rounded corners is here:
http://malsup.com/jquery/corner/
On January 23, 2009
9:47AM
Billy Gray said:
Cool plugin, dude, thanks ;-)
On February 25, 2009
2:23PM
Natalie said:
Hi Rob, I’ve made a Drupal module with your plugin. Do you mind if I publish it?
On February 25, 2009
5:36PM
Natalie said:
Hi Rob, thanks, of course I mentioned you and your site in the module docs.
On February 26, 2009
6:43PM
Paul said:
Rob,
I’m a newbie building a web site based on Dave Woods CSS Fixed Footer,http://www.dave-woods.co.uk/index.php/css-fixed-footer/ . When I apply your equal height plug-in the content, if longer than the page, rides up over the top of the footer, instead of behind it. Is there a way to fix that?
Thanks
On March 03, 2009
5:41AM
Oliv G. said:
A little improvment of your plugin that supports the padding and border sizes…
(function($) {
$.fn.equalHeights = function(minHeight, maxHeight) {
var tallest = (minHeight) ? minHeight : 0;
function addSize(elem,baseHeight,operation) {
var border_top = parseInt(elem.css(’border-top-width’));
var border_bottom = parseInt(elem.css(’border-bottom-width’));
var padding_top = parseInt(elem.css(’padding-top’));
var padding_bottom = parseInt(elem.css(’padding-bottom’));
if (operation == ’subtract’) {
if (!isNaN(padding_top)) baseHeight -= padding_top;
if (!isNaN(padding_bottom)) baseHeight -= padding_bottom;
if (!isNaN(border_top)) baseHeight -= border_top;
if (!isNaN(border_bottom)) baseHeight -= border_bottom;
} else {
if (!isNaN(padding_top)) baseHeight += padding_top;
if (!isNaN(padding_bottom)) baseHeight += padding_bottom;
if (!isNaN(border_top)) baseHeight += border_top;
if (!isNaN(border_bottom)) baseHeight += border_bottom;
}
return baseHeight;
}
this.each(function() {
var height = $(this).height();
height = addSize($(this),height);
if (height > tallest) tallest = height;
});
if((maxHeight) && tallest > maxHeight) tallest = maxHeight;
return this.each(function() {
tallest2 = addSize($(this),tallest,’subtract’)
$(this).height(tallest2);
});
}
})(jQuery);
On March 30, 2009
9:20AM
Aaron said:
I’m trying to use this with the jQuery UI themes and can’t seem to get around the IEx v6 problem of the containers including images with undefined heights.
My goal is to display text of an unknown length in buttons and to have all buttons in a given row have equal heights. Therefore the height of the images is unknown ahead of time. Any suggestions? Perhaps something in this plugin to define the height of the images?
On March 30, 2009
10:26AM
Rob Glazebrook said:
Hi Aaron,
I believe you can get around this problem by using $(window).onload() instead of $(document).ready(). Using document.ready results in your columns being set more quickly — but it runs before all of your images have been downloaded. By contrast, window.onload doesn’t fire until everything — including your images — is downloaded.
The downside is you’ll have a second or two of unequal columns before the script fires. The upside is, your columns should work well, even in IE.
On April 20, 2009
9:37AM
Tim said:
I use this plugin on a page where most of the pages content is loaded using ajax. Of course when I loaded data dynamically my columns wouldn’t resize, as is expected.
To fix this, you would think you would just call .equalHeights() whenever you added or removed data. However this doesn’t work, the reason being that the plugin sets the height of the elements on the first run and calling it again it uses these set heights to recalculate the values (at least in firefox, never tested IE).
To get around this I just do .height(’auto’).equalHeights().
On April 20, 2009
11:30AM
Rob Glazebrook said:
This is a great tip, Tim. Thanks for sharing!
On May 07, 2009
4:58PM
Matthew said:
Thanks, works in Fx and IE7. Fixed two separate sets of columns in minutes! Would have hated to use a table… Thanks again!
On May 26, 2009
4:34PM
Jeremy said:
I have a problem that needs a solution very similar to this plugin, but with a twist. The site design is using a 3-column, variable-width layout. That was difficult enough to make work properly, but the downfall with how we made it work was that we can’t clear floats in the content column (see site here: http://knowledgenetwork.thunderbird.edu/tpec/?theme=Thunderbird+3). If we clear:left, it causes the content below the clear to jump down below the bottom of the left column, and same thing with clearing right columns. So the problem is that we need each post summary to have a min-height of the image that is left aligned, so that the following post summary isn’t wrapped around the image as well. This plugin would make all post summaries the height of the tallest one (or require specifying a min-height, which is never known, since it is dependent on the posts being displayed on the images included in those posts). It would be ideal if this plugin could be slightly modified so that each element to be resized could simply look at the image size specified in the element and make that the min-height the same. That way each element could have a different min-height specified, according to it’s own content. All it would basically do is mimic what a clear:both would do (if only we could use clears!).
On June 16, 2009
3:06AM
maxpabby said:
is there a way to implement this with columns that have different classes
On June 16, 2009
3:16AM
maxpabby said:
also my columns are nest in a div(cont2) which is in another div(cont1) and I want the columns to take the background colour of “cont2″ keeping in mind that the body background colour is different for both divs
sorry for the complexity but that’s where I find myself
On June 16, 2009
4:53AM
maxpabby said:
found the answers seems i should have taken my j-script-query serious however am thinking, what if i have two groups of columns that needs to be of equal height differently.
let say i have div 1&2 which needs to be of the same height with a min height of say 100 and 3&4 which also need to be of thief own height with a min height of say 150
can i implement such with the current plug-in
On June 16, 2009
10:41AM
Rob Glazebrook said:
Hi Maxpabby,
If you have two distinct groups, then the plugin works fine… you just have to run it twice. So you would have something that looks like this:
$(”.group1″).equalHeights();
$(”.group2″).equalHeights();
Or, if you don’t have classes set up for your divs, you can group them in your jQuery like so:
$(”#div1, #div2″).equalHeights();
$(”#div3, #div4″).equalHeights();
Hope that helps!
On June 16, 2009
4:09PM
maxpabby said:
thanx rob u are the best
i just thought it would be nice to be able to style the scrollbars i found a plug-in for it but its too long
anyway for those having problems with the scrollbar i discovered that that setting the div’s overflow to “scroll” hides the bars and makes them appear only when the content changes dynamically