5

I've got a few DIV tags with different amounts of text content.

HTML:

<div id="boxes">
    <div id="boxone">
        <p>...</p>
    </div>
    <div id="boxtwo">
        <p>...</p>
    </div>
    <div id="boxthree">
        <p>...</p>
    </div>
    <div id="boxfour">
        <p>...</p>
    </div>
</div>

They're in a two-by-two layout and their width is fluid:

CSS:

div#boxes {
    width: 100%;
}

div#boxes div {
    width: 49.9%;
    float: left;
}

I want them all the same height.

So, I loop through them and find the height of the tallest one. Then I loop again and set them all to that height.

jQuery:

$(function() {
    var maxHeight = 0;
    $('div#boxes div').each(function(){
        if (maxHeight < $(this).height()) {maxHeight = $(this).height()}
    });
    $('div#boxes div').each(function(){
        $(this).height(maxHeight);
    });
});

This works well if the height of the div doesn't need to change again.

But, it fails if I resize the browser window:

  1. If I (a) make the browser wider, then (b) my DIVs get wider, then (c) their text content wraps fewer times, and then (d) my DIVs are too tall.

  2. If I (b) make the browser more narrow, then (b) my DIVs get narrower, then (c) their text content wraps more, and then (d) my DIVs are too short.

How do I both (1) automatically size DIVs to the height of their content like normal, but also (2) keep those multiple DIVs the same height?

Zack Peterson
  • 56,055
  • 78
  • 209
  • 280

5 Answers5

6

For the others who, like me, came here by searching Google for a solution: The fist part of the accepted answer only works when the first div is the highest. I have made some changes to it and now it seems to work in all cases.

var highest = 0;
function sortNumber(a,b)    {
    return a - b;
}

function maxHeight() {
    var heights = new Array();
    $('#wrapper2>div').each(function(){
        $(this).css('height', 'auto');
        heights.push($(this).height());
        heights = heights.sort(sortNumber).reverse();
    });        
        highest = heights[0]; 
    $('#wrapper2>div').each(function(){
        $(this).css('height', highest);
    });

}

$(document).ready(function() {
    maxHeight();
})

$(window).resize(maxHeight);
Jarco
  • 1,635
  • 4
  • 14
  • 22
4

Update... completely rewriting this answer after experimenting and finding another, apparently workable way to do this:

function sortNumber(a,b)    {
    return a - b;
}

function maxHeight() {
    var heights = new Array();
    $('div#boxes div').each(function(){
        $(this).css('height', 'auto');
        heights.push($(this).height());
        heights = heights.sort(sortNumber).reverse();
        $(this).css('height', heights[0]);
    });        
}

$(document).ready(function() {
    maxHeight();
})

$(window).resize(maxHeight);

One thing I noticed is that IE really has rounding troubles with 50% wide floated divs... the rendering was much better if I changed those to 49%.

This jQuery works...

// global variables

doAdjust = true;
previousWidth = 0;

// raise doAdjust flag every time the window width changes

$(window).resize(function() {
    var currentWidth = $(window).width();
    if (previousWidth != currentWidth) {
        doAdjust = true;
    }
    previousWidth = currentWidth;
})

// every half second

$(function() {
    setInterval('maybeAdjust()', 500);
});

// check the doAdjust flag

function maybeAdjust() {
    if (doAdjust) {
        adjustBoxHeights();
        doAdjust = false;
    }
}

// loop through the DIVs and find the height of the tallest one
// then loop again and set them all to that height

function adjustBoxHeights() {
    var maxHeight = 0;
    $('div#boxes div').each(function(){
        $(this).height('auto');
        if (maxHeight < $(this).height()) {maxHeight = $(this).height()}
    });
    $('div#boxes div').each(function(){
        $(this).height(maxHeight);
    });
}
Zack Peterson
  • 56,055
  • 78
  • 209
  • 280
RwwL
  • 3,298
  • 1
  • 23
  • 24
  • maxHeight is always the same every time adjustBoxHeights() executes. The DIV heights are never allowed to change back to their natural/automatic heights. – Zack Peterson Apr 29 '09 at 20:29
  • How do I remove the height style from a DIV using jQuery? http://stackoverflow.com/questions/804161/how-do-i-remove-the-height-style-from-a-div-using-jquery – Zack Peterson Apr 29 '09 at 20:40
  • $(selection).height('auto') seems to work in addition to the $(selection).css('height', 'auto') in my example above. – RwwL Apr 29 '09 at 21:21
  • None of .height('auto'), .css('height', 'auto'), or .attr('height','') work for me. – Zack Peterson Apr 29 '09 at 21:29
  • Where/how exactly are you trying to use it? Somewhere in your original function? – RwwL Apr 29 '09 at 21:41
  • Just verified locally -- using .height('auto') right before the first .each in your original code (chained, right after the selector and before the .each) seems to work fine. You have to set them to auto before you start measuring and manipulating them; maybe that's the issue you're having. I'm using jQuery 1.3.2 for these tests; btw. Not sure how much the height function has changed over the last few updates, if at all. – RwwL Apr 29 '09 at 21:49
  • It seems that resizing the DIVs causes the window to resize which causes the DIVs to resize which causes... etc. – Zack Peterson Apr 29 '09 at 21:51
  • I got it to work. I added my final code to your answer. Thank you for your help. – Zack Peterson Apr 29 '09 at 22:34
2

Check out this jQuery Plugin which allows you to monitor a CSS property such as the height.

pjesi
  • 3,931
  • 3
  • 20
  • 16
  • If you find an answer to be incorrect and you vote it down, please at least give a reason. – pjesi Apr 30 '09 at 08:03
0

If you want it to work when resizing etc... Do it like this:

function sortNumber(a,b) {
    return a - b;
}

var highest = 0;

function maxHeight() {
    var heights = new Array();
    $('.equalheight div').css('height', 'auto');
    $('.equalheight div').each(function(){
        heights.push($(this).height());
    });        
    heights = heights.sort(sortNumber).reverse();
    highest = heights[0]; 
    $('.equalheight div').css('height', highest);
}

$(document).ready(maxHeight);
$(window).resize(maxHeight);
Bram
  • 1
0

I found this solution to be a bit more tidy for my situation. It works regardless of which div is the highest. Based it on this old Chris Coyier post at CSS Tricks.

function maxHeight() {
    var maxHeight = 0;
    $(".container > .post-box").each(function(){
       if ($(this).height() > maxHeight) { maxHeight = $(this).height(); }
    });
    $(".container > .post-box").height(maxHeight);
}

$(document).ready(function() {
    maxHeight();
}

$(window).bind('resize', function () {
    $(".container > .post-box").css('height', 'auto');
    maxHeight();
}).trigger('resize');

However, I did need to set the height to auto on resize before running the function again. I didn't need to set it in the original function because it was set in the css.

J May
  • 181
  • 4
  • 7