Varying Column Heights in Bootstrap

The complete guide to “clearfix”

Carol Skelly
Mar 13, 2017 · 8 min read

About once a week on Stack Overflow, I see the exactly same question asked. It’s always has the same answer, but the question is asked in many different ways…

— “Why does Bootstrap grid new line not look nice?”

— “Why are there gaps in my image grid?”

— “Why are the Bootstrap columns wrapping unevenly?”

— “How can I align images of different height?”

— “How to reduce whitespace between grid rows?”

— “Why don’t the Bootstrap grid columns wrap evenly?”

— “What’s causing my fluid grid layout issues?”

— “How can I stack columns of different height?”

__”Irregular bootstrap column wrapping


The Problem

Pictures always help, so here’s a visual. Notice that the columns, starting with the 4th column, don’t wrap evenly to the next row…

Ideally, the 4th column would stack under the 1st.

Often, when people encounter this problem, they’ll have a theory as to what’s causing it.

The problem is NOT caused by:

— The number of columns.

— The type of content inside the columns: Images, text, or both.

— The width of the columns.

— Having more than 12 column units in a single .row element*.

Varying types of content, or width doesn’t cause a problem

The problem is caused by one thing:

— The content inside the columns. The height of the content makes each column a different height.

Varying content height does cause a problem

For the remainder of this article, I will refer to this irregular columns issue as the “height problem”.


What really causes the height problem?

The Bootstrap height issue occurs because the columns (col-*-*) use float:left. When a column is “floated” it’s taken out of the normal flow of the document. It is shifted to the left or right until it touches the edge of its containing box. So, when you have uneven column heights, the correct behavior is to stack them to the closest side.


Important! Responsive design

Before looking at solutions, I want to further qualify the height problem.

The following solutions & workarounds are designed for true responsive layouts that utilize Bootstrap’s column wrapping __ this is an essential component of responsive design with Bootstrap, and most responsive grid systems.

Some designers out there think that you must limit each .row to 12 columns, and don’t understand column wrapping. Sadly, I’ve even seen this poor guidance in the W3Schools Bootstrap tutorial.

That guidance is very misleading:

“Note that numbers in .col-*-* should always add up to 12 for each row.” — W3schools.com

Please, if you think “each row can only have 12 columns”, or if you don’t understand why there would ever be more than 12 columns in a .row, don’t read any further, and read this instead!


Solutions & Workarounds

1 — Equal height columns

In most cases, the height of the content is unknown, but there are a few ways to make each column the same height as adjacent columns…

Bootstrap 3 Equal Height Columns

Equal-height Option 1 —
— Make the columns the same height as the tallest column.

In this scenario, each row of columns will be the height of the tallest column in the row. This is a widely-used solution for the height problem. There are several options for making the columns the same height as the tallest column.

Important! People will often suggest using tricks like table-cell or huge negative margins & padding to make the columns the same height. When it comes to responsive design, these are both bad ideas. If you don’t understand why these aren’t viable “equal height” solutions, or column wrapping read no further, and read this instead.

As of 2017, CSS3 flexbox is the best CSS-only equal height option to make the columns equal height.

.row.display-flex {
display: flex;
flex-wrap: wrap;
}
.row.display-flex > [class*='col-'] {
display: flex;
flex-direction: column;
}

Before flexbox…

Varying height causes irregular column wrapping

The height issue solved with equal height flexbox…

Use flexbox to make equal height columns

Equal-height Option 2 —
— Force the column content to be equal in height:

Beyond making the columns equal height with flexbox, another option is to make the column content equal in same height. However, this is only an option for some use cases.

Consider a grid of “cards” with a text heading and image in each. The images are all the same known height, but sometimes the headings are longer, and therefore wrap. The classic height problem due tofloat:left becomes apparent…

In this case, a simple fix may be to force the headings to a one line, and prevent the text wrapping:

.panel-body h2 {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

The height issue solved (long headings are truncated with ellipsis)…

Again, this is a little trick that usually won’t work in scenarios with dynamic content, but it’s handy to know.


Equal-height Option 3 —
Set a static column height:

Lastly, the most obvious of the CSS “same height” solutions. I mention it last because the height of our columns is generally unknown. But, it’s still the simplest option…

.row.force-height>div {
height: 500px;
}

Equal-height Option 4 —
JavaScript or jQuery plugins:

The focus of this article is CSS, but there are some JavaScript options for making same height divs. One of the more popular options is the match-heights plugin.


2 —Clearfix: Force columns to wrap every X columns

Another solution to solve the height problem is to use “clearfix” which basically removes the float from the rightmost column, so the next adjacent column can wrap properly to far left of the next row.

Bootstrap 3 Clearifx

Clearfix Option 1 —
Responsive “reset” DIV’s in the HTML markup:

The official Bootstrap recommended approach to solving the height problem is known as “responsive resets”. The nice thing about this clearfix option is that it’s responsive, and everything you need is already included in Bootstrap.

As explained in the docs, you simply add a .clearfix div for the required viewports, or grid tiers. So in our responsive layout, we need a clearfix every 2 columns on small screens (xs), and every 3 columns on larger (md and up) screens.

<div class="row">
<div class="col-md-4 col-xs-6"> 1 </div>
<div class="col-md-4 col-xs-6"> 2 </div>
<div class="clearfix visible-xs">
<!-- clearfix xs cols every 2 -->
</div>
<div class="col-md-4 col-xs-6"> 3 </div>
<div class="clearfix visible-md">
<!-- clearfix lg cols every 3 -->
</div>
<div class="col-md-4 col-xs-6"> 4 </div>
<div class="clearfix visible-xs">
<!-- clearfix xs cols every 2 -->
</div>
<div class="col-md-4 col-xs-6"> 5 </div>
<div class="col-md-4 col-xs-6"> 6 </div>
<div class="clearfix">
<!-- clearfix all breakpoints -->
</div>
<div class="col-md-4 col-xs-6"> 7 </div>
<div class="col-md-4 col-xs-6"> 8 </div>
<div class="clearfix visible-xs">
<!-- clearfix xs cols every 2 -->
</div>
<div class="col-md-4 col-xs-6"> 9 </div>
...
</div>

The height problem solved with responsive resets…

Responsive reset Demo:
http://www.codeply.com/go/HmRrGFqrvl

The only thing that can get a little tricky with responsive resets is when you have dynamically generated columns. The iterative loop that generates the columns must insert the appropriate clearfix div after every X columns which can become more complicated for multiple grid tiers.


Clearfix Option 2 —
CSS-only clearfix using nth-child selectors:

This solution is similar to the last, except it’s done using CSS nth-child(..) selectors for the end (rightmost) columns in each viewport “row”.

Since the medium (-md-) viewport in Bootstrap applies on screens widths of 992 pixels and up, we “clear” our floats every 3 columns on larger screens.

@media (min-width:992px){
.row.auto-clear .col-md-4:nth-child(3n+1){clear:left;}
}

Similarly, we clear the floats for less than 992 pixels (-xs- and -sm-) every 2 columns on smaller screens. Eventhough we’re not using col-sm-6 in the markup it’s assumed since col-xs-6 means “small and up” unless specifically overridden for the sm grid tier…

@media (min-width:992px){
.row.auto-clear .col-md-4:nth-child(3n+1){clear:left;}
}
@media (max-width:991px){
.row.auto-clear .col-xs-6:nth-child(2n+1){clear:left;}
}

CSS-only clearfix demo:
http://www.codeply.com/go/3v7Q9kQVR6


As I said earlier the type of content of the columns doesn’t matter, and clearfix will work in all cases. Here’s an example of clearfix columns with responsive tables that vary in height.

Either clearfix approach (HTML or CSS) will work to clear the float:left and fix the uneven grid wrapping height problem. However, it’s important to note that clearfix is not a “masonry” solution.


3 — Masonry: Make columns fit like “Pinterest”

It’s important to understand that neither the “same height”, nor clearfix solutions will make the columns into a Masonry-like layout like this..

A “Masonry” Layout

There isn’t anything native in Bootstrap 3.x that will create this type of layout. Basically, Masonry layouts are out-of-scope for Bootstrap 3, but it’s still possible using both CSS or JavaScript based options.

Masonry Option 1 —
— Use CSS3 columns:

.row.make-columns {
-moz-column-width: 19em;
-webkit-column-width: 19em;
-moz-column-gap: 1em;
-webkit-column-gap:1em;
}
.row.make-columns > div {
display: inline-block;
padding: .5rem;
width: 100%;
}

Masonry with CSS3 Columns Demo:
http://www.codeply.com/go/qnPaEqNcgE

CSS3 columns will be an offering in the upcoming Bootstrap 4. Currently with this solution columns are always ordered top-to-bottom, and then left-to-right. This is sometimes a downside in use-cases where the normal left-to-right flow is expected.


Masonry Option 2 —
— Use “Masonry”, or other similar jQuery plugin:

Another way to create a Masonry layout is using the very popular plugin, or one of the many others. Here’s a Bootstrap Masonry example to get you started.


In summary, there are 3 ways to solve the Bootstrap height problem:

Equal height columns

Clearfix

A “Masonry” solution


Still here? With the soon-to-be-beta Bootstrap 4, the “height issue” will become a non-issue since Bootstrap 4 uses flexbox, and therefore the columns in each row will be equal height. Although, perhaps this will introduce an alternate problem? https://stackoverflow.com/questions/44710785/bootstrap-4-i-dont-want-columns-to-have-the-same-height/44710904

Please let me know your thoughts in the comments!

WDstack

Tools, apps & insight on design + development

Carol Skelly

Written by

S/W Engineer. Web developer. @Bootply @Codeply

WDstack

WDstack

Tools, apps & insight on design + development

More From Medium

More from WDstack

More from WDstack

How-to… Bootstrap

3.2K

More on Web Development from WDstack

More on Web Development from WDstack

Vue JSON Lint

16

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade