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
On August 09, 2009
5:26AM
Anwar Javed said:
I think instead of setting height we should use min-height to allow columns to resize automatically.
(function($) {
$.fn.equalHeights = function(minHeight, maxHeight) {
tallest = (minHeight) ? minHeight : 0;
this.each(function() {
if($(this).height() > tallest) {
tallest = $(this).height();
}
});
if((maxHeight) && tallest > maxHeight) tallest = maxHeight;
return this.each(function() {
if ($.browser.msie && $.browser.version == 6.0) { $(this).height(tallest); }
$(this).css(“min-height”, tallest + “px”).css(“overflow”, “auto”);
});
}
})(jQuery);
On August 09, 2009
5:51AM
Anwar Javed said:
Also Setting overflo auto shows scrollbar in IE.
(function($) {
$.fn.equalHeights = function(minHeight, maxHeight) {
tallest = (minHeight) ? minHeight : 0;
this.each(function() {
if($(this).height() > tallest) {
tallest = $(this).height();
}
});
if((maxHeight) && tallest > maxHeight) tallest = maxHeight;
return this.each(function() {
if ($.browser.msie && $.browser.version == 6.0) { $(this).height(tallest); }
$(this).css(”min-height”, tallest + “px”);
});
}
})(jQuery);
On August 09, 2009
7:54AM
Rob Glazebrook said:
Hi Anwar,
There are a few problems with using min-height. First is that Internet Explorer (at least through version 7, I haven’t tested 8) doesn’t support it. So while min-height would work in other browsers, it would fail completely in IE, rendering the plugin useless with the majority of web users. And yes, you can get around that by setting height for IE and min-height for the others, but I was shooting for consistency. :)
The other problem is, the whole idea behind this plugin is to get elements of the exact same height. Using the height property assures this. Using min-height does not: any element could stretch beyond its minimum height, becoming taller than the others and potentially ruining a layout that was dependent on equal heights.
On August 09, 2009
4:52PM
Olivier G. said:
@Anwar @Rob : I also tend to prefer to use min-height rather than pure height for such designs, but there are some curious rendering issues with firefox 3 using this method. I often have to add 1px to the min-height to prevent rendering bugs like the browser thinking that one of the elements his higher than he is, and so creating a “hole” in the design.
On August 11, 2009
7:22AM
Jim said:
Hi Rob,
I’m using your plugin, but I ran into a problem. My page ahs a two column layout. The left has some plain text, and the right has a form inside. This form includes a radio button that controls the visibility of a part of the form. When the radio button says not to show a hidden part of the form, there is still whitespace below the page. When a click the radiobutton to show the hidden part of the form, then the whitespace is filled with the rest of the form.
I think your equalheights plugin can’t handle the hidden part of the form properly, because there is whitespace at the bottom of the page ‘as room’ for the hidden fields of the form. I would like that when the part of the form is hidden, than the extra whitespace should not be there.
I hope you can help me with this. Thanks!
On August 11, 2009
12:52PM
Olivier G. said:
@Jim : I think that you just have to apply again the plugin in you show/hide function on the two columns.
On August 25, 2009
1:15PM
joe zielinski said:
I’m having issues with this working in Safari 3. Any Ideas?
On September 13, 2009
9:39AM
lenny aspen said:
thanks Rob that`s a nice solution
the best so far
anyway on opera i replaced this line:
$(this).height(tallest).css(“overflow”,”auto”);
with this line
$(this).height(tallest).css(“overflow”,”hidden”);
so the right scrolling bar wont show
On September 25, 2009
9:47AM
Sara said:
Rob –
Thanks for this great solution!
However, I’ve run into a glitch I can’t seem to resolve. The resize appears to be running fine, but it’s resizing SMALLER than the tallest box.
Here’s an example of what I’m talking about:
http://workbench.deliverframework.net:8006/myron/?No=12&D=notepads&Ntt=notepads&Nao=12&Di=1000&Dk=0&N=0&Nty=1
I am trying to resize the “prod-info” class that contains the description of various products so that my pricing grids and buy buttons will all be equally aligned on this search page. The Regatta Burgundy & Black Compac® Diary description is clearly the longest on the page, but the pricing grid is being pushed into the text in Firefox, and in IE, it just forces the Buy button lower and displays mis-aligned.
I tried the fix of .height(‘auto’).equalHeights(), but that didn’t seem to help. Adding the resize function seems to fix the overlapping text issue in Firefox, but that still leaves the buy button mis-aligned.
Any thoughts/suggestions would be greatly appreciated! We’re hoping to launch this on Tuesday!
Thanks!
Sara
PS – Congratulations on your marriage!
On September 25, 2009
10:05AM
Sara said:
An addendum to my original comment. It’s this line in the Javascript that causes the problem:
$(this).height(tallest).css(“overflow”,”visible”);
When set to “auto” it works fine, but displays a scrollbar (in IE and Firefox)
When set to “visible” I have that word wrap issue.
When set to “hidden” the box still doesn’t stretch correctly, but at least the text is hidden.
As a potential fix I’ve set the Javascript to overflow hidden, and defined a minimum height of 55px, but I wish there was a better solution…
Thanks again!
On December 02, 2009
5:30PM
Jason Bartholme said:
Thank you for the plugin! I was pulling my hair out trying to get a Grid960 layout to get equal columns. I will be using this script in the future.
On December 18, 2009
9:32AM
Julien said:
Great plugin, thank you !
On December 29, 2009
3:39AM
Custom WordPress themes said:
I can say, “I know jquery!”. Why? Because of the contribution of people like you. Thanks.
I should say, “I know how to use jquery!”.
On January 26, 2010
4:08AM
naruto said:
Thank so much for your supports.
On February 05, 2010
4:59PM
Marjorie said:
Hi Rob –
Love the plugin. However I’ve got a small problem. The plugin doesn’t seem to work with the jQuery.js version that my website uses (v1.3.2). Doesn’t work with the latest version either (v1.4.1).
I’ve tested it with the version that your website uses (v1.2.6) and it works fine.
However, will this break my website if I load 2 separate versions of jQuery.js in the section? My website runs Wordpress 2.9.1.
As you can guess, I know nothing about jquery/javascript. Hope you can clear my confusion and concerns.
Thanks in advance.