Nicholas Cerminara
This tutorial is out of date and no longer maintained.
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.
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:
.cols
http://codepen.io/ncerminara/pen/PNLRXW
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):
Here’s how to match heights on different rows:
$(function() {
$('.box').matchHeight();
});
http://codepen.io/ncerminara/pen/GZedpW
Here’s how to match the height of all elements on the page:
$(function() {
$('.box').matchHeight(false);
});
http://codepen.io/ncerminara/pen/NNJMWX
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;
}
}
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 div
s 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.
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:
It also has a lot of cons though:
.btn
). There are workarounds for this, but it’s unnatural a bitoverflow: 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
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.
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 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 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.
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.
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!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.