On Bootstrap’s Grid: Using display: inline-block instead of floats

I had the opportunity to use Twitter’s Bootstrap on a project recently, and I’ve been really impressed by how well their grid system is built. I used the LESS version of the Bootstrap UI, which is amazingly flexible. My main grievance is that they’ve chosen to structure the basic grid by using CSS floats.

The problem with floats

The problem with using CSS floats comes when you have grid elements of varying, or unpredictable height. In the example below, the divs should line up in a 4-column grid, but because the first item in column 3 is too tall, what should be the bottom item in column 1 actually gets stuck behind the too-tall top item from column 3. Now the alignment on the second and third rows is all messed up.

1
2
3
4
1
2
3
4
1
2
3

Using display: inline-block instead

Fortunately, there’s another method we can use to get our grid lined up the way we want it–display: inline-block! The only catch is that inline-block elements natively render with a small space between each item. So if you want to use exact measurements for your grid, 25% width for each item in a 4-column grid, you’ll notice that the last column drops to form a new row because of the space added between the inline-block elements.

1
2
3
4

There are a number of ways to get rid of this space, but I think most of them are a bit too hack-y to be ideal solutions. It seems like the easiest solution is to remove the whitespace between elements in the HTML, e.g., <li>A list item</li><li>A second list item</li>

Getting it just right

However, if your grid elements are dynamically generated, it may not always be possible to create this HTML structure. Therefore, my personal favorite method to remove the whitespace is to apply a negative margin around each grid element. By default, the added whitespace is about .25em wide. So, I just apply margin: 0 -0.125em; to each grid element, and, voilá, the grid looks just right!

With inline-block, we can also vertically-center any dangling items. Say, for instance, your last row only has 3 items. If it suits your design, you can easily center those 3 items in the row by applying text-align: center to the parent container. Ultimately, if you’re going to have elements that vary extremely in height, you might also want to use the Masonry Javascript plugin to avoid big, uneven gaps in the vertical rhythm.

1
2
3
4
1
2
3
4
1
2
3

Implenting the override

To implement my display: inline-block override, I just redefined these methods in a new file, overrides.less. By making the overrides in a new file instead of overwriting the Bootstrap source code, I can more easily update the Bootstrap source without losing my changes.

.make-xs-column() { float: none; display: inline-block; margin: 0 -0.125em; }
.make-sm-column() { @media (min-width: @screen-sm-min) { float: none; display: inline-block; margin: 0 -0.125em; } }
.make-md-column() { @media (min-width: @screen-md-min) { float: none; display: inline-block; margin: 0 -0.125em; } }
.make-lg-column() { @media (min-width: @screen-lg-min) { float: none; display: inline-block; margin: 0 -0.125em; } }


About the Author:

11 thoughts on “On Bootstrap’s Grid: Using display: inline-block instead of floats

  1. Pingback: Ausklappbare Spalten mit Bootstrap | Wolfgangs Blog

  2. Fantastic! I kept searching for a solution since morning. This solved it :) Thanks you so much Kim :)

  3. Fantastic fix… I had arrived at a similar solution (using inline-block) but your fix for the whitespace is great. Thanks for sharing.

  4. Oh man, I really like this approach. Obviously there’s a lot of overhead with bootstrap going into the whole thing, but being able to use columns nicely, well, float have never ever been my friend, whereas inline-block is so simple, and so nice. Of course, it does have that one annoying quirk of the spaces between elements, and that’s made more disruptive because as far as I remember, the actual “em” width of the space is dependent upon the font-size of container elements, or line-height or something. But if it works to use -0.125em, then that should be about good enough.

    1. Thanks! Yes, I’ve always preferred inline-block to floats, but it seems like the web dev community as a whole prefers floats. They each have their quirks, of course… Hopefully one day soon we’ll all be able to use flexbox!

  5. This post was great help to me. Thanks!

  6. I took over a project that forced me to use Bootstrap for the first time today. The big reason I haven’t bothered before is because Bootstrap uses floats for their grid. Thank you so much for this post. I used this as a reference to do the same thing using bootstrap-sass and added some utility classes for vertical alignments. Here is the snippet if anyone came across this solution that was looking for a sass version.

    1. Thanks, Conrad–I’m glad I could help!

  7. Great post. I always prefer to work with display: inline-block; instead of floats. And for this particular use (in grids) I think it’s much better and give you more alternatives.

    Regarding the ‘white space’ between elements I prefer to use font-size: 0; for the parent element (‘row’ in the grid system) and reset it again in the element, for example with font-size: 1rem; (‘column’ in the grid system). I think is better than the negative margin and fits any scenario. The only disadvantage is that doesn’t work on ‘pre Jellybean’ Android browsers.

  8. margin: 0 -0.125em; that magic number is font dependant. You will run into issues with other fonts or if the content is rendered on one line without line breaks.

  9. Hi Kim – this is very interesting – but I have 2 questions:

    1. You apply left and right negative margins of -0.125em – but as a previous poster (Roy) mentioned ems are related to body font-size. Do you have a more precise (i.e. px or rem) equivalent?

    2. What happens if you apply your negative margins, upload to the client’s website and the html gets minified – surely that will now break the design?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>