
The goal: Dynamic, equal heights
Sometimes you’d like to have several elements that will all be the same height, no matter what content they have inside them. In other words:

You don’t want this

You want this
This is devilishly hard with straight CSS (if you’re not using tables, which you generally shouldn’t be for layout).
But it’s pretty easy with JavaScript/jQuery. Here’s a demo!
How to do it
Here’s the code:
(function($){
function equalizeHeights(selector) {
var heights = new Array();
// Loop to get all element heights
$(selector).each(function() {
// Need to let sizes be whatever they want so no overflow on resize
$(this).css('min-height', '0');
$(this).css('max-height', 'none');
$(this).css('height', 'auto');
// Then add size (no units) to array
heights.push($(this).height());
});
// Find max height of all elements
var max = Math.max.apply( Math, heights );
// Set all heights to max height
$(selector).each(function() {
$(this).css('height', max + 'px');
});
}
$(window).load(function() {
// Fix heights on page load
equalizeHeights(MYSELECTOR);
// Fix heights on window resize
var iv = null;
$(window).resize(function() {
if(iv !== null) {
window.clearTimeout(iv);
}
// Needs to be a timeout function so it doesn't fire every ms of resize
iv = setTimeout(function() {
equalizeHeights(MYSELECTOR);
}, 120);
});
});
})(jQuery);
You’ll need to change ‘MYSELECTOR’ above to whatever CSS selector defines all the elements whose heights you want to equalize (most likely a class, like .content-block
).
Once you’ve done that, save the code as a .js file, drop it in anywhere on the page after jQuery is loaded, and you’re ready to go!
Notes
- Other, very similar solutions exist—here’s one. The major difference is that the solution presented here fires automatically on page load and window resize, rather than needing to be called manually.
- The function first fires directly after the window finishes loading, meaning that items may “flicker” from different sizes to the same size. Unfortunately,
$(document).ready
won’t work, because the items may not have heights yet. - The function will also fire anytime the user resizes his or her screen, meaning that items stay the same height even as lines break differently.
- If box-sizing is set to border-box (which we recommend), you’ll need to rework this code to add each element’s vertical border and padding to its height—or else the tallest element will overflow by the amount of its vertical borders + vertical padding.
Enjoy!
Hope the script works for you! Would love to hear questions or comments.
Image Credits: Paul and Jill
Thank for sharing this is working for me. and it save my time thank you so much.
Thank you so much! I’ve been breaking my head over this. This is the easiest solution I could find for my WordPress site using Foundation Zurb (Foundation’s own Equalizer didn’t seem to work).
Thanks for sharing! It helps me to fix my own function.
What if I want to have multiple rows of content resize with varying heights, is there a way to do that without having to duplicate the script? I assume I can’t use the same class as it will give both rows the same height.
Hi Jeff,
Great question. If I’m understanding you properly, you actually only need to duplicate the function call for each row and the script will work as you like; it calculates new heights each time the function is called.
The solution you’re after would look like:
$(window).load(function() {
// Fix heights on page load
equalizeHeights(SELECTOR1);
equalizeHeights(SELECTOR2);
// Fix heights on window resize
$(window).resize(function() {
// Needs to be a timeout function so it doesn't fire every ms of resize
setTimeout(function() {
equalizeHeights(SELECTOR1);
equalizeHeights(SELECTOR2);
}, 120);
});
});
Or slightly more elegant would be:
$(window).load(function() {
// Fix heights on page load
equalizeAllHeights();
equalizeAllHeights();
// Fix heights on window resize
$(window).resize(function() {
// Needs to be a timeout function so it doesn't fire every ms of resize
setTimeout(function() {
equalizeAllHeights();
equalizeAllHeights();
}, 120);
});
});
function equalizeAllHeights() {
var selectors = [SELECTOR1, SELECTOR2]
$(selectors).each(function(index, item) {
equalizeHeights(item);
});
}
I haven’t tested that second way of doing it, so let me know if it’s buggy and I’ll try to fix.
How about multiple rows with different heights? Is there a way to do this without having to use the same function multiple times?
Worked like a charm, thanks!
🙂
Hello, this is rather old but I just found this.
Notice that the timeout at the end doesn’t throttle the calls, it just sets them to execute in 120ms. You’ll still have the same amount of calls to equalizeAllHeights(), they just kick in 120ms later (but after 120ms you notice no difference in delay)
To make it work, save the timeout ID and clear it before each setTimeout
var iv = null;
$(window).resize(function() {
if (iv)
window.clearTimeout(iv);
iv = window.setTimeout(equalizeAllHeights, 120);
});
This would actually make sure that resizing in a 120ms frame you’ll only get once call. Only after 120ms the handler is fired once.
Hi Torben,
Wow, you’re absolutely right! I’ve altered the code to reflect your fix.
Thanks so much for writing!
Fred
Hi,
Thanks, this works really well.
How can I stop the equal height kicking in when the browser width is less than 768px?
@Simon Clay
I’d try wrapping the equalizeHeights(MYSELECTOR) functions in an if statement to check if window width is greater than 768px.
Something like:
if ( $(window).innerWidth() > 768 ) ){
equalizeHeights(MYSELECTOR);
};