Post

Different Tricks on How to Make Bootstrap Columns All the Same Height

Draft updated on Invalid Date
    author

    Nicholas Cerminara

    Different Tricks on How to Make Bootstrap Columns All the Same Height

    This tutorial is out of date and no longer maintained.

    Introduction

    Bootstrap 3 (and now Bootstrap 4) are amazing CSS frameworks that can make the lives of developers of any skill-level easier. When I was more of a beginner and I first started using Bootstrap, I used every feature of it possible and used to hack it to get things to work the way I wanted. Now, with more experience, I mostly just use their reset and grid system. I now rarely alter any of its core functionality.

    Bootstrap’s grid system is fantastic and near-perfect in my opinion. You can read about it here. I often see developers needing to match heights across columns while maintaining responsiveness. I’ve decided to share some of the methods I do to accomplish this, as well as some very cool tricks other developers and friends have taught me, and the general direction and solution that Bootstrap 4 is doing to address this common problem.

    Equal Columns? The Problem.

    I’ve made a demo CodePen to illustrate the issue when the content in columns is different lengths and how it messes with design. Some quick notes first:

    • Padding of 25px is added to the top and bottom of all Bootstrap stuff
    • A subtle border wraps all .cols
    • Various backgrounds are used to see how things stack on each other and how this all works

    http://codepen.io/ncerminara/pen/PNLRXW

    Option 1: Use JavaScript or MatchHeight.js

    The first solution I’m going to use is with JavaScript. This is pretty straightforward and simply uses JavaScript to match the heights of the columns. The best, easiest, and almost the most “official” JS way is to simply use matchHeight.

    There are definitely pros and cons to taking a JavaScript approach. With JavaScript, you get high cross-browser support, but you also have a bigger pageload and it won’t happen until the DOM is ready or loaded depending on when you trigger it. I like this approach though because I actually prefer to not have heights associated with my columns and instead the content in them.

    Here’s more info on matchHeight.js:

    The quickest way to get started is just reference the CDN link like so after your jQuery:

    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery.matchHeight/0.7.0/jquery.matchHeight-min.js"><script>
    

    MatchHeight is super easy-to-use and essentially has two main options (among a bunch of other stuff):

    • Match heights on different rows
    • Match all heights

    Match heights on different rows

    Here’s how to match heights on different rows:

    $(function() {
      $('.box').matchHeight();
    });
    

    http://codepen.io/ncerminara/pen/GZedpW

    Match all heights

    Here’s how to match the height of all elements on the page:

    $(function() {
      $('.box').matchHeight(false);
    });
    

    http://codepen.io/ncerminara/pen/NNJMWX

    Don’t forget responsive

    If you take either of these approaches, make sure to disable heights on mobile since the columns are all stacked it won’t matter if they’re the same height or not.

    You can just override the fixed height at the media query breakpoint. This changes based on xs, sm, md, or lg). Here’s a demo when using col-sm-*:

    @media only screen and (max-width : 767px) {
      .box {
        height: auto !important;
      }
    }
    

    Option 2: Make the row think it’s a table

    The word “table” usually sets off a bunch of red flags with front-end developers, but it’s really not that bad when used right. A lot of people don’t even realize you can force divs and its elements to behave like a table element.

    Sometimes you want to do this because the table element’s columns have matched height as a default behavior. Here’s a CSS utility class to trick rows into thinking it’s a table when you’re using col-sm-* followed by a demo:

    @media only screen and (min-width : 768px) {
      .is-table-row {
        display: table;
      }
      .is-table-row [class*="col-"] {
        float: none;
        display: table-cell;
        vertical-align: top;
      }
    }
    
    <div class="row is-table-row">
      <div class="col-sm-4">...</div>
      <div class="col-sm-4">...</div>
      <div class="col-sm-4">...</div>
    </div>
    

    http://codepen.io/ncerminara/pen/EKMLXx

    You’ll have to adjust this a bit based on what size column you’re using. So it would actually make sense to create multiple utility classes: is-xs-table-row, is-sm-table-row, is-md-table-row, and is-lg-table-row or just manually make sure you check for responsive.

    You’ll also notice I adjusted the styles a bit because the columns now have a height (not the custom .box element). If you take this approach, you’ll have to plan for this.

    Option 3: Using a Negative Margin and Huge Padding Trick

    This approach is really, really cool and probably the best solution for most people. I have no idea who came up with it, but it is super creative and has many benefits:

    • Works on responsive out-of-the-box with little thinking
    • Little effort from the developer to make sure it works well in various scenarios
    • Should work on all columns regardless of their sizing

    It also has a lot of cons though:

    • Positioning elements absolute to the bottom is not possible (see the CodePen adjusted styles on .btn). There are workarounds for this, but it’s unnatural a bit
    • Required to have “row” have overflow: hidden

    Here’s a utility class for it:

    .row.match-my-cols {
      overflow: hidden;
    }
    
    .row.match-my-cols [class*="col-"]{
      margin-bottom: -99999px;
      padding-bottom: 99999px;
    }
    
    <div class="row match-my-cols">
      <div class="col-sm-4">...</div>
      <div class="col-sm-4">...</div>
      <div class="col-sm-4">...</div>
    </div>
    

    http://codepen.io/ncerminara/pen/EKMLeP

    How does it work?

    It adds 99999px of height to the column via padding and then uses the negative margin to force the position as if it is not there. Then the .row just hides anything that is overflowed.

    Option 4: Use Flexbox

    Flexbox is the CSS3 God’s gift to the world of grumpy front-end developers. It’s the ultimate tool for layouts and “gridding” via CSS. You can learn all about it with this Visual Guide to CSS3 Flexbox Properties.

    There’s only one problem. Internet Explorer browser support is awful. IE9 and below provides zero support, IE10 is a crapshoot with it, and IE11 has many bugs. It’s really only useful to a select few privileged developers, but know Flexbox is coming and here to stay.

    This method does equal heights, is super easy, is out-of-the-box responsive, and has everything you can ask for. Here’s a demo:

    .row.is-flex {
      display: flex;
      flex-wrap: wrap;
    }
    .row.is-flex > [class*='col-'] {
      display: flex;
      flex-direction: column;
    }
    
    /*
    * And with max cross-browser enabled.
    * Nobody should ever write this by hand.
    * Use a preprocesser with autoprefixing.
    */
    .row.is-flex {
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-flex-wrap: wrap;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }
    
    .row.is-flex > [class*='col-'] {
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-orient: vertical;
      -webkit-box-direction: normal;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
    }
    
    <div class="row is-flex">
      <div class="col-sm-4">...</div>
      <div class="col-sm-4">...</div>
      <div class="col-sm-4">...</div>
    </div>
    

    http://codepen.io/ncerminara/pen/qZvYgR

    Bootstrap 4 Only: Flexbox

    Bootstrap 4 will have two options for its grid: “With Flexbox” and “Without Flexbox”. If you opt-in with the Flexbox option, the heights are matched automatically. You can read more about it at What’s New in Bootstrap.

    Here’s an awesome demo showing the beauty of it:

    http://codepen.io/ncerminara/pen/EjqbPj

    The problem is still browser support and Bootstrap 4 is, as of writing this, not production-ready and in alpha version.

    Bootstrap 4 Only: Cards

    Bootstrap 4 also introduced a concept called “Cards”. Cards are defined as “a flexible and extensible content container. It includes options for headers and footers, a wide variety of content, contextual background colors, and powerful display options.”.

    You can read more about it here.

    Really, all it means is it gives you out-of-the-box Bootstrap styles for the .box demoed in these CodePens. This is really cool though because there are many options to match height on columns. The only thing is it’s not technically part of the “grid”, but is a phenomenal solution for matching heights of columns regardless.

    Here’s a demo:

    http://codepen.io/ncerminara/pen/gpVXxz

    What’s cool about Cards in Bootstrap 4 is if you don’t opt-in with Flexbox, it will use tables to trick the heights of the columns to match. If you do, it will use Flexbox instead. This is one of the most exciting things about Bootstrap 4 in my opinion.

    More Resources

    Bootstrap is simply a framework. At the end of the day, it’s ultimately up to you or the developer to make it work the way you want with your design. You can use all these methods, some of these methods, or whatever. It really doesn’t matter so long you understand the pros and cons.

    I personally don’t like making CSS adjustments on any base bootstrap thing: .container, .row, .col-*-*. I think it’s too easy for developers to do unintentional things that alter the grid itself (like adding left or right margin or padding) and breaking the default functionality. It’s really up to you though!

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about our products

    About the authors
    Default avatar
    Nicholas Cerminara

    author

    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
     
    Leave a comment
    

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Featured on Community

    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

    Become a contributor

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

    Learn more