What’s the Deal With Display: Inline-Block?

by on 29th February 2012 with 48 Comments

screenshot

We’ve been using floats for layout pretty much since we left tables behind. It’s a quirky solution that can often cause troubles, but if you know what you’re doing, it works.

One interesting alternative to floats that people are turning to more and more lately is to set the display value of an element to inline-block. What does this do exactly? How is it like a float? How is it different? Let’s dive in and see what we can discover.

The Display Property

Web browsers render different elements in different ways. Some elements are block-level, meaning that their default display value is set to block. Block-level elements have a definable width and height and automatically create a new row in the layout as they’re created.

One example of a block-level element is a paragraph. If I toss two paragraphs into a HTML document, they stack on top of each other rather than appearing side by side. I have a lot of freedom over their dimensions and can really treat them as individual building blocks to shape as I please.

screenshot

Other elements have their display value set to inline by default. This means they don’t have a definable height and width and will not create new rows in a layout (thus they appear “inline”). Inline elements are generally the type of thing that you institute within a paragraph or other block-level element: strong, em, anchor, etc.

Here’s what happens if I toss a bunch of anchor tags into an HTML document. Unlike the the paragraphs above, which automatically stack, these elements are created side by side. Their width and height are determined by the content they contain and can’t be manually overridden as with the block-level elements.

screenshot

There are a few other basic display default values that you’re probably familiar with as well. For instance, items in the head portion have a display property of none.

Setting Your Own Display Value

One really interesting feature of CSS is the ability to change the default display behavior of elements. Though a standard behavior is already set for a given element, we can override that for our own purposes.

For instance, we can easily take those inline anchor tags from the second example above and make them act more like the block-level paragraphs from the first example. We do this be setting the display property to block in our CSS.

screenshot

Now our anchor tags behave like block-level items, so each one creates a new line and can have a custom height/width value applied.

As you can imagine, it’s more difficult to work with the reverse of this example by taking a block-level element and setting the display value to inline. Instinctively, you might use display: inline to try to make the two paragraphs above appear side by side, but when you do this, the result is instead that the two flow together into a single paragraph.

screenshot

We’ve now lost all ability to set our width and height so the two paragraphs are inexorably integrated, which isn’t at all what we were going for.

Floating Elements

So what if we want the two paragraphs above to remain distinct but appear side by side as individual columns instead of stacked into rows? The typical answer that many of us have turned to for years is floats. By applying “float: left” to the paragraphs, we can maintain block-level functionality while creating multiple columns of content.

screenshot

Floats come with some interesting behavior. For instance, floated items tend to collapse their parent container, leading to all kinds of messy issues if you’re applying background colors or borders. To get around this, we have a few tricks. We can either clear the floats on a new element (these days it’s often a pseudo-element) at the end of the container or use overflow:auto on the parent. Both fixes have their caveats, but if you know how to leverage each properly you can typically pull off any layout feat without too much trouble.

display: inline-block

There are tons of values for the display property beyond what we’ve mentioned already, some of which are helpful, others that I doubt you’ll ever use. The topic of today’s discussion is by far one of the most interesting and useful of the bunch: inline-block.

Watch what happens when we take our two paragraphs from the original example above and apply a display value of inline-block.

screenshot

Looks a lot like a float right? So what happens if we add in a parent container? Does it have the collapsing problem that we saw with floats? Nope! Everything works just how we expect it to.

screenshot

What’s happening here is that we’re telling the browser to display the paragraphs inline, but allow them to retain their block-level characteristics. This means we can set a width and height manually and have the two elements remain distinct, but also have them appear next to each other in the document flow. Pretty slick!

The Alignment Issue

On the surface, inline-block may seem like the layout savior you’ve been waiting for. Who wants to mess with messy clearfix hacks when you can skip it altogether with this method? It turns out though that floats aren’t the only layout method with quirks, inline-block also has some strange functionality that you have to wrap your head around.

One of the first things that you’ll floats and inline-block look quite different when you have several elements with varying heights. For instance, here’s what happens when you float a bunch of paragraphs to the left:

screenshot

Now here’s what happens when you use inline-block to pull off the same thing. Notice that the bottom edges of the paragraphs are aligned instead of the top as in the previous image.

screenshot

Fortunately, this isn’t a huge problem. To address the issue, make sure you set the vertical-align property to top.

screenshot

The Whitespace Issue

There’s another important place that the behavior of inline-block differs from floats. I find it bizarre that anything in HTML and CSS could be whitespace aware when it comes to layout, but that’s exactly what we find here. Consider the following examples.

screenshot

Here we can see that when a group of list-items is floated, they smash right up against each other like we would expect, allowing us to manually set the gap without any unexpected extra space. However, when we do the same with inline-block, there’s a little bit of default space that won’t even go away if we set our margins to 0.

As you can see, one solution is to take out the whitespace in our HTML and push the elements right up against each other. Once again, I find this pretty confusing but it does work. An alternative solution that produces the same result without screwing with the visual hierarchy in your HTML is to apply a margin of -4px on the list items.

screenshot

Browser Support

Now that we know what inline-block is and how it functions differently than floats, it’s time to discuss everyone’s favorite topic: browser support. What atrocities will we have to embark upon to make sure this technique actually works across the board?

When we stop by CanIUse.com to see the answer, the results are probably a lot better than you would’ve expected.

screenshot

Here we can see that we have at least partial support across the board and full support for everything but IE7 and older (feigned shock and awe). The note at the bottom informs us that inline-block is “only supported in IE6 and IE7 on elements with a display of ‘inline’ by default.” This means that the paragraph examples that we’ve used all throughout this article are out.

Fortunately, the Mozilla blog posted some fixes for this way back in 2009. To get IE to play along nicely, we just need to trigger hasLayout with the zoom property and then use the star hack to target IE6/7 and set the display to inline. This allows you to functionally treat the inline elements as if they were inline-block elements. It’s certainly not pretty, but it gets the job done.

li {
  display: inline-block;
  width: 100px;
  vertical-align: top;

  /*Dirty IE Hack*/
  zoom: 1;
  *display: inline;
}

Further Reading

If you’d like to learn more about inline-block, here are some articles that I found to be particularly helpful in my research.

A Better Solution?

To be honest, I’ve never really played around with inline-block too much before today, but I’ve been seeing more and more suggestions in the comments that I explore this method as an alternative to floats so I thought I’d take the advice. I was hopeful going into it that it was indeed some magic, no-hassle way around floats, but in truth it really isn’t. There are still several unexpected behaviors that you have to know about and respond to, resulting in some hacky code much like we often see with float clearing fixes.

To be fair though, it is in fact a pretty simple way to accomplish float-like layouts. More importantly, the CSS that you have to implement to make sure it’s cross-browser compatible is briefer than even the popular micro clearfix hack from Nicolas Gallagher. This may make it a better way to go for many projects.

Ultimately, I think I will in fact begin adding this method to my bag of tricks. I suspect that certain times will arise when floats aren’t ideal (example: right floats render everything in reverse) and this will be a great alternative to have in those situations.

What do you think? Is inline-block a good alternative to floats? What situations can you think of where one clearly has an advantage over the other?

Comments & Discussion

48 Comments

  • Dels

    Since we live in the world full of CSS (Grid) Frameworks, can you suggest CSS (Grid) Framework based on inline-block?

  • Ian

    What about setting the display to table-cell for creating columns?

    In the pargraph example above you could set the #container to display:table and the p to table-cell

  • http://medieutvecklaren.se Fredrik

    @Ian: I think the browser support for table-cell is not as high. I haven’t looked it up, but when I tried to use it once (a couple of weeks ago) I ran into problems, I think with IE.

  • http://iamnatalia.com Natalia Ventre

    Certainly it’s something to consider, I like the inline-block method for horizontal navigation, but for layout, when there’re only 2 columns, I float one left and the other right, I don’t specify margins, and that’s a small time saver for me.

  • Ian

    @Fredrik It dosent have partial support in IE 6&7 but full support looks to be the same: http://caniuse.com/#search=table-cell

  • http://www.captivatedesigns.com/ Website Redesign

    Since we live in the world full of CSS (Grid) Frameworks, can you suggest CSS (Grid) Framework based on inline-block?

  • David Hucklesby

    No need for the “zoom” in your last example. “Inline-block” applies the necessary “hasLayout” for geriatric IE. Just be sure to put the “*display: inline;” in a separate rule. This does what you want without taking away “hasLayout” for some odd reason.

  • http://twitter.com/giuseppegurgone Giuseppe
  • Martin Zahuta

    There’s one more way of dealing with the whitespace generated between inline blocks. Simply set the font-size of the parent element to 0 and you’re done! You can then do something like #parent * { font-size: whatever; }

  • Rick Lowes

    I’m aware of 2 grid frameworks that use inline-block –

    YUI3 Grids CSS:
    http://yuilibrary.com/yui/docs/cssgrids/ (non-minified CSS is here: http://yui.yahooapis.com/3.4.1/build/cssgrids/grids.css)

    And Stacklayout : http://www.stacklayout.com/

    I’ve used both and seem to work well.

  • http://www.webmosphere.co.uk Dave Black

    I guess I’m gonna have to stick to floats for a while. That little 4px whitespace would have caused me major future nightmare had I not been through here! thanks for the great analysis.

  • David Hucklesby

    One fix for the spacing, without hacks or ugly markup, that I used way back when – leave off the closing LI from the list items. Valid HTML 4.01 and HTML5 – but not XHTML of course.

    BTW – the gap is not 4px – it’s the width of a space character, which depends on the font and font size.

  • Jeremy Brown

    If you were wondering why inline-block keeps breaking in IE7 its the space between aligned elements. http://ow.ly/8Qzz3
    Stupid right?

  • http://paintndesign.com phil

    Regarding the clearfloats issue, i have never this problem with my parent container even if i dont set any overflow properties. Why do you need a overflow property for parent containers with floated elements when you can just set a height for parent containers?

  • http://www.digitalkeydesign.com DKD

    Great article. I was just messing with this on a website build I’m doing. This was just what I needed to get me going and solve my minor space issue. Thanks!

  • Ralph

    Great article. I do use inline-block where I normally would have used a float more often these days and there are indeed several ways to overcome the white space issue.

    @Phil – What if you don’t know how long the content of the children will be? Especially if you have authors that insert content through a CMS. It’s best practice to let the content dictate the height of the parents, so a clearfix method is your best friend with this.

  • http://www.newlegendmedia.com Jeff Hilton

    I recently developed my new grid system that I use for web projects based entirely on inline-block. If you set the container to be display:inline-table it fixes the whitespace issue quite nicely. Also, the recent buzz about using box-sizing:border-box prompted me to try adding that to my grid and it help tremendously with adding borders and padding to grid elements without breaking the grid.

    Thanks for this very clear writeup on in-line block!

  • http://joshnh.com Josh

    Great write up. I really enjoyed the detail you went into.

    In regards to the 4px fix: it’s only 4px if the font size is 16px (the default in most browsers). So in reality, the rendered white space is 25% of the font-size. Therefore, a safer solution is to actually use margin-right: -.25em;

    There are other solutions too, such as commenting out white space in the markup, or setting a font-size of zero on the parent element.

  • Pete Cinema

    Is it any wonder that flash was/is so popular? You may not like flash or know how to use it, but the kind of non-sense that is described in the preceding examples and issues is rendered moot with flash. It is totally absurd in 2012 that we have browsers that render the same stuff in different ways for various reasons. Imstead of coming up with fixes that are browser specific everyone in the development community aught to out in the streets rioting… what the hell are standards for if they are not “Standard”. Can you imagine an automaker coming up with a variation on how a steering wheel works or the brake pedal works? Domyou thing the driving public would tolerate such absurdity? Go figure.

  • http://bittersmann.de Gunnar Bittersmann

    Inline blocks are a good alternative to floats. I’ve been advocating this for quite some time. [http://bittersmann.de/articles/inline-block/] (in German, but you’ll get the picture from the pictures – no pun intended)

    If only there wasn’t the whitespace issue… But “to apply a margin of -4px on the list items” is not a good solution. A webpage author cannot know which font in which size will be used on the user’s system. And even the same font in the same size might be rendered differently on different systems (browsers / OS). It’s not safe to say that the width of a space is 4px.

    word-spacing: -100% [http://www.w3.org/TR/css3-text/#word-spacing] looks promising, but does not work in current browsers.

  • http://www.shakebiz.fr Doubouil (fr)

    I don’t remember where I saw this :

    .container {
    white-space: nowrap;
    }
    .children {
    display: inline-block;
    vertical-align: top;
    white-space: normal;
    }

    Seems working. Also, setting container’s text-align to center and children to left allow centered childrens.

  • Dragos

    Great article indeed!
    with some experience in font-end everyone one should know that there isn’t such thing as the perfect solution but in each case you have a choice to make.
    Indeed the inline-block followed by zoom:1; and *display:inline does the job well in most cases, but there were situations when I had to do a pixel perfect grid and that gap of 3-4px was ruining it so thank you for the font:0 tip, just tested and it’s really great!
    However, I wouldn’t rely on it 100% and for some other cases I will use the float with clearfix because having to redeclare font may cause problems with the consistency.
    Table-cell is pretty nasty and I had big problems with it in IE7 – I did try to use it in combination with some positioning which didn’t work well in all the browsers except FF, oh well..

  • http://www.betleywhitehorne.com Ric

    I’ve been using inline-block for about a year now and it’s wonderful. Although the upcoming CSS3 layout specs should be much, much better yet. Here’s an example: http://www.lovellsproperty.com/

  • Nicholas Camp

    What’s the problem about using float:left with a clearfix? I don’t get the point… Using inline-block you need to apply some fixes to work in ie7-. That’s a better approach? Thank you!

  • http://www.stygyan.es stygyan

    I’ve found that inline-block can be pretty useful in horizontal navigation. It allows you to center navs in a pretty way.

  • mic

    Very nice article. But I have one problem, maybe someone could help me. In your example with paragraphs, when I put some list inside the p it jump out from the inline-block line, I mean columns aren’t in the same line, any ideas?

  • SimonC

    The spacing issue should not be a surprise, because you’re defining the elements to be displayed inline. Even if they are then also displayed as blocks, the page flow will treat them as inline elements – part of the text, with everything that implies; ie that white space will be treated as white space in the same way as it would if you had spaces between two words of text.

    Your 4px solution to it is also wrong. What you’re seeing between the boxes are space characters. These are not guaranteed to be 4 pixels wide; it will depend on the browser and the font.

    There are a variety of other solutions to it. You could try setting the font size to zero in the container element (but beware of cascading style issues with that), or you could try altering you HTML so there’s no white space between the elements (there’s various ways to do this, although none of them look good when you view the code).

    There is also a proposed direct CSS solution to this:
    white-space-collapsing:discard;
    is intended to directly solve this problem with inline blocks.
    However the spec for this style is still under discussion, so it probably won’t be available for use for some time yet, so for the foreseeable future, you’ll have to use hacks to get around it.
    See http://www.w3.org/TR/2010/WD-css3-text-20101005/#white-space-collapsing for more info.

  • phrequency

    From what I understand, you get greater IE support for using inline-block on native inline elements. So putting it on an ‘li’ vs an ‘a’ tag will yeild different results in IE browsers. I use this for navigation sometimes where I want a quick and dirty horizontal nav and can’t have li’s.

  • http://bittersmann.de Gunnar Bittersmann

    @SimonC: “This section is still under discussion and may change in future drafts.”

    Well, it has changed. There’s no such property ‘white-space-collapsing’ anymore. You have referred to an outdated working draft (2010-10-05).

    The property was still in its successor http://www.w3.org/TR/2011/WD-css3-text-20110215/#white-space-collapsing before being renamed to ‘bikeshedding’ http://www.w3.org/TR/2011/WD-css3-text-20110412/#white-space-collapsing (”Issue: Need a property name”), and eventually to ‘text-space-collapse’ http://www.w3.org/TR/2011/WD-css3-text-20110901/#white-space-collapsing

    As such, it still appears in the current working draft, but the value “discard” has been dropped http://www.w3.org/TR/2012/WD-css3-text-20120119/#white-space-collapsing

    So this property would not help.

  • http://www.facebook.com/gps816 Sovit Ranjitkar

    display inline-block always shocks me a lot coz of unwanted whitespace so i always use float left. but this article helps me to clean up unwanted whitespace. i must say thanks a lot great share..

  • http://www.facebook.com/gps816 Sovit Ranjitkar

    *sucks

  • http://anti-code.com Jared Williams

    I’ve been using inline-block since I started making websites. I never learned to do things using the clearfix way until last year, after 9 or so, I just read so many reasons to not use it and lucky for me had read an article like this long ago that got me using inline-block from the start. Never had any real headaches or problems of any kind.

    I try to get people who use clearfix to stop and instead use inline-block, it’s just so much better and smarter.

  • http://atern.us Kiril Reznik

    @Ric

    Great website Ric. You have an annoying content flash issue for the slideshow, you could easily solve it with display:none and :first-child { display: block }.

    Thanks for the article! YUI grid will definitely come handy when working with RTL/LTR websites.

  • http://sushilbharwani.blogspot.com sushil bharwani

    Very nice explanation. Thanks for clarifying this. Also could you please add a little more explanation for clear:both property on clearing floats. What does that mean and how does it solves it.

  • mundi

    leave off the trailing LI tag…

    http://codepen.io/pen/mundizzle/1/1

  • Alex

    @Jared Williams, how would you make it work in IE6/7? inline-block is rendered as “inline” in those browsers.

  • http://www.petrchutny.cz Petr Chutný

    Thanks, great article. I’ve found myself switching to the inline-block very often recently.

  • Dave Colburn

    There’s a way to deal with collapsing parent containers that you didn’t mention: float the parent. A floating parent element will “shrink wrap” around its child elements.

  • http://codebycoady.com Alex Coady

    I think those -4px margins are too much for me, I was so hopeful there weren’t going to be any cons! Great article, thank you.

  • http://permainanberpakaian.blogspot.com/ game berpakaian

    Very amazing articles. But I have one problem, maybe someone could help me. In your example with phrases, when I put some history in the p it jump out from the inline-block variety, I mean articles are not in the same variety, any ideas?

  • Felix

    Maybe this could help :3

    http://masonry.desandro.com/

  • carine

    WOW….thanks for this…I always read of how to do stuff but I always forget…its nice to have a tutorial on WHY stuff works…that way we can make informed decisions

  • Ryan Hoffmann

    Awesome write up.

    Thanks for this!

  • @TheLoneCuber

    Whilst a definite “hack”, I guess you could solve the whitespace issue by using the non-breaking space html entity   ? Simply add it after each closing li. This would solve all validation issues (wouldn’t it?) and it would ensure that any minified HTML that is served would render as expected.

  • Przemek

    Thankfully columns are coming! :D

  • Steve

    Thanks. Great article.

  • http://inklink.co.at Bruno

    Great article! thanks for clarifying this topic!! I always asked myself the difference between both…

  • http://www.fix4query.in anand

    Good article explaining about inline-block and float, inline.

Subscribe

Membership
About the Author