50

Does bootstrap 2.0 have any helpers to make .span1, .span2 .... .span12 equal height. I've nested this type of html

<div class='container'>
  <div class='row'>
    <div class='span2'>
      <div class='well'>
        XXXX
      </div>
    </div>
    <div class='span2'>
      <div class='well'>
        XXXX
        XXXX
      </div>
    </div>
    <div class='span2'>
      <div class='well'>
        XXXX
        XXXX
        XXXX
      </div>
    </div>
  </div>
</div>

I would like each well to end up the same height if possible?

vcsjones
  • 138,677
  • 31
  • 291
  • 286
bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217

8 Answers8

73

Here's a responsive CSS solution, based on adding a large padding and an equally large negative margin to each column, then wrapping the entire row in in a class with overflow hidden.

.col{
    margin-bottom: -99999px;
    padding-bottom: 99999px;
    background-color:#ffc;
}

.col-wrap{  
    overflow: hidden;   
}

You can see it working at jsFiddle

Edit

In response to a question, here's a variation if you need equal height wells or equal height columns with rounded corners: http://jsfiddle.net/panchroma/4Pyhj/

Edit

In response to a question, here's the same technique in Bootstrap 3, same principle, just update the class names in the Bootstap grid: http://jsfiddle.net/panchroma/bj4ys/embedded/result/

David Taiaroa
  • 25,157
  • 7
  • 62
  • 50
  • 1
    One drawback, the background is drawed and jsut hidden because of the overflow. Meaning if you render something else then a static color you dont see the bottom border. try it together with call well on each column. – Poul K. Sørensen Apr 16 '13 at 08:51
  • @s093294 , if you want to start a jsFiddle, we might be lucky and be able to find a solution in your specific case. – David Taiaroa Apr 16 '13 at 11:53
  • http://jsfiddle.net/teFYS/109/ just updated the one from here abit to illustrate my problem. – Poul K. Sørensen Apr 16 '13 at 12:40
  • Tried adding the col wrappers my self also, just didnt make it work. Thanks :) – Poul K. Sørensen Apr 18 '13 at 08:39
  • Is there a way to make it so the columns are as least as long as the screen if the content is shorter than a screen? – Richard Garside Jun 07 '13 at 15:29
  • (Answering my own question) Set min-height: 100% on .col-wrap – Richard Garside Jun 07 '13 at 15:39
  • One problem with this approach -- it's problematic if you have anchor links you want to jump to on the page (ie, go to foo). It will hide the content before #foo. See http://jsfiddle.net/mark47/yDKsS for an example. I'm trying to come up with a workaround. – Voodoo Jul 12 '13 at 20:00
  • 1
    I'm pretty sure this solution is based on http://www.positioniseverything.net/articles/onetruelayout/equalheight.html, no? – Heraldmonkey Aug 07 '13 at 09:32
  • @JoshM. ... you have to take care with borders because they add width to elements and could break the Bootstrap grid. Two options are to use box-sizing: border-box (see http://css-tricks.com/box-sizing/ ) or wells as in my edit above: http://jsfiddle.net/panchroma/4Pyhj/ – David Taiaroa Sep 14 '13 at 19:50
  • 1
    Yes, but if you're just letting the inner boxes grow vertically and cutting them off at some arbitrary height, then some boxes may grow past the outer box, cutting off the bottom border. Unless I misunderstood this solution. – Josh M. Sep 15 '13 at 01:54
  • @JoshM. , check the result of the edit : http://fiddle.jshell.net/panchroma/4Pyhj/show/ This is one option, no doubt the code could be improved as well. – David Taiaroa Sep 15 '13 at 03:39
  • this works for bootstrap v2.1.0 but not bootstrap v3.1.1 – pro Mar 19 '14 at 12:06
  • @DavidTaiaroa - your edit works for bootstrap v3.1.1 - very useful - thanks – pro Mar 20 '14 at 09:20
  • 1
    hey @HelloWorldNoMore, the large padding bottom extends the shortest column so that it is longer than the content area of the longest column. This will also extend the other columns, but don't worry about that. It will also push down elements after this row, so we add a matching negative margin to offset this. Finally the overflow: hidden is to stop any background colour from extending beyond the bottom the content area of the longest column. – David Taiaroa Apr 26 '16 at 22:50
16

Try something like this (not very elegant, though):

$('.well').css({
    'height': $('.well').height()
});

The jQuerys height() method returns the highest value when multiple elements are selected.

See the jsFiddle: http://jsfiddle.net/4HxVT/

gregory
  • 1,140
  • 2
  • 11
  • 27
  • 1
    Just tried this but `height()` actually returns the first element: "Description: Get the current computed height for the first element in the set of matched elements." http://jsfiddle.net/p4ekd/ – Chris Conley Jul 03 '12 at 23:25
11

jQuery's height() method returns the value of the "first element in the set of matched elements". The answer in http://jsfiddle.net/4HxVT/ only works because the first element in the row is also the highest.

Here's another jQuery based solution:

http://www.filamentgroup.com/lab/setting_equal_heights_with_jquery/

(Via this answer: https://stackoverflow.com/a/526316/518535)

Community
  • 1
  • 1
Tim Brayshaw
  • 482
  • 3
  • 9
4

Expanding upon the answers already given, I have just solved this using jquery and underscore. The snippet below equalizes the height of my wells and alerts that appear on a given row, regardless of where the tallest one appears:

$('.well, .alert').height(function () {
    var h = _.max($(this).closest('.row').find('.well, .alert'), function (elem, index, list) {
        return $(elem).height();
    });
    return $(h).height();
});
ahsteele
  • 26,243
  • 28
  • 134
  • 248
jstewmon
  • 76
  • 3
2
$.fn.matchHeight = function() {
  var max = 0;

  $(this).each(function(i, e) {
    var height = $(e).height();
    max = height > max ? height : max;
  });

  $(this).height(max);
};

$('.match-height').matchHeight();
galatians
  • 738
  • 7
  • 12
1

I solved this with a custom jQuery max plugin:

$.fn.max = function(selector) { 
    return Math.max.apply(null, this.map(function(index, el) { return selector.apply(el); }).get() ); 
}

Here content-box is my internal column element, content-container is the wrapper that contains the columns:

$('.content-box').height(function () {
  var maxHeight = $(this).closest('.content-container').find('.content-box')
                  .max( function () {
                    return $(this).height();
                  });
  return maxHeight;
})
ahsteele
  • 26,243
  • 28
  • 134
  • 248
György Balássy
  • 2,938
  • 1
  • 28
  • 23
0

The above solutions all work until you add nice bootstrap buttons! How do you position buttons I thought (yes, that was my problem).

I combined the CSS with the jquery answer from How might I force a floating DIV to match the height of another floating DIV?

After a bit of frigging I got this, which works with CSS although the buttons don't line up, and is fine with jQuery

Feel free to fix the CSS button line up bit :)

jQuery:

$.fn.equalHeights = function (px) {
    $(this).each(function () {
        var currentTallest = 0;
        $(this).children().each(function (i) {
            if ($(this).height() > currentTallest) {
                currentTallest = $(this).height();
            }
        });
        if (!px && Number.prototype.pxToEm) {
            currentTallest = currentTallest.pxToEm(); //use ems unless px is specified
        }
        // for ie6, set height since min-height isn't supported
        if ($.browser.msie && $.browser.version == 6.0) {
            $(this).children().css({
                'height': currentTallest
            });
        }
        $(this).children().css({
            'min-height': currentTallest + 40 // THIS IS A FRIG - works for jquery but doesn't help CSS only
        });
    });
    return this;
};

$(document).ready(function() {
    var btnstyle = {
    position : 'absolute',
    bottom : '5px',
    left : '10px'
    };
    $('.btn').css(btnstyle);
    var colstyle = {
    marginBottom : '0px',
    paddingBottom : '0px',
    backgroundColor : '#fbf'
    };
    $('.col').css(colstyle);    
    $('.row-fluid').equalHeights();
});

CSS

.col {
    margin-bottom: -99999px;
    padding-bottom: 99999px;
    background-color:#ffb;
    position:relative;
}
.col-wrap {
    overflow: hidden; 
}

.btn{
   margin-left:10px ;   
}
p:last-child {
 margin-bottom:20px ;   
}

jsfiddle - http://jsfiddle.net/brianlmerritt/k8Bkm/

Community
  • 1
  • 1
0

Here is my solution with 2 columns (adapt this to more columns is simple, just add more conditions). Run on the load event to have the correct heights of all elements.

$(window).on('load', function () { 
    var left = $('.left');
    var leftHeight = left.height();
    var right = $('.right');
    var rightHeight = right.height();

    // Width like mobile, the height calculation is not needed
    if ($(window).width() <= 751)
    {
        if (leftHeight > rightHeight) {
            right.css({
                'height': 'auto'
            });
        }
        else {
            left.css({
                'height': 'auto'
            });
        }

        return;
    }

    if (leftHeight > rightHeight) {
        right.css({
            'height': leftHeight
        });
    }
    else {
        left.css({
            'height': rightHeight
        });
    }
});

<div class="row">
    <div class="span4 left"></div>
    <div class="span8 right"></div>
</div>
HolloW
  • 720
  • 11
  • 21