Should You Use Inline-Blocks As A Substitute For Floats?

When it comes to developing a site layout with css, floats do most of the heavy lifting. We use them for the big blocks like our main content and sidebar and we use them for the smaller blocks inside these big ones. Are floats always the answer?

They generally work well, but sometimes they can be hard to work with. This is especially true when it comes to inside blocks like a grid of images that won’t line up as expected. Inline-blocks are another option we can use. They mimic some of the behaviors of floats that we want, while not holding some of the issues we don’t.

Inline-blocks aren’t anything new and it’s quite possible you’re already using them. I haven’t until recently. The last few sites I’ve built happened to be for photographers and the sites naturally called for grids of images and I find myself reaching for inline-blocks over floats.

CSS box model

What is an inline-block?

Inline-block is one of the values we can assign to the display property of an element. It gets its name because it has some of the characteristics of inline elements and some of block elements.

  • block elements — form boxes according to the css box-model. They have width, height, padding, border, and margin and they stack vertically on top of each other.
  • inline elements — don’t form boxes. They sit horizontally next to each other.
  • inline-block elements — act like block elements on the inside where they form boxes. On the outside they act like inline elements sitting horizontally next to each other instead of stacking on top of each other.

If you think about it, that’s not too far off from how a floated elements behaves. Floats form boxes, but they also sit next to each other instead of stacking vertically. They aren’t exactly the same of course, but the inline on the outside and block on the inside characteristics are sometimes all we really want and either a float or an inline-block might be appropriate.

How text flows around a floated block and an inline-block

The Difference Between Floats and Inline-Blocks

While floats and inline-blocks share some characteristics, there are some clear differences between the two.

  • Document flow — Floats are removed from the normal document flow allowing other elements to flow around them. Inline-blocks stay in the document flow. They don’t need to be cleared so no clearfix solutions or overflow: hidden. Of course other elements can’t flow around them and you can’t force an element below an inline-block by clearing it.
  • Horizontal position — An obvious case of this is floats can’t be centered by setting text-align: center on the parent element. In fact no positioning style you place on the parent will affect a floated element. The inline part of inline-blocks lets their parent affect their position.
  • Vertical alignment — inline-blocks align on the baseline by default. Floats align at the top. You can change the default and control where inline-blocks are vertically aligned. You can’t do this with floats. This has been the main reason I’ve been using inline-blocks more, which I’ll get to in a bit.
  • Whitespace — inline-blocks pick up html whitespace. If you have several inline-block elements each on a new line in your html they’ll display with a horizontal space between them. Floated elements will sit adjacent to each other, regardless of the html whitespace between them.
  • IE6 and IE7 — inline-blocks aren’t supported or only have partial support in IE6 and IE7. If you need to support those browsers you need to find a workaround. Probably not a big issue at this point, but worth mentioning.
Showing the whitespace issue with inline-floats
All the blocks above are set to display: inline. On the left there is whitespace between them in the code. On the right the html whitespace has been removed. That’s the only difference.

Solving the Whitespace issue

It’s possible, even likely you’ll want to use inline-blocks at times, but don’t want the horizontal space between them. There are a few methods for removing it.

  • Remove the html whitespace — Get rid of the new line character between elements in some way. Not always an elegant solution, but one that works, especially if you only have a few elements.
  • Use negative margins — You can set a negative margin equal to the space.You’ll have to adjust for the font-size as the space is based on that size. I want to say it’s 0.25em, but I’m not entirely sure. If anyone knows please leave a comment.
  • Set a font-size of 0 on the parent — No matter what size the space, a font-size of 0 means the space would also be equal to 0. Naturally you’d need to reset the size for any children that need to have a font-size.

Edit: As Matt pointed out in the comments below the font-size: 0 trick does work on Android. You can see an example Matt created on CodePen

wooden blocks floating in the bathtub
Wooden blocks floating in a bathtub

When To Use Inline-Blocks and When To Use Floats?

When to use either depends on the specifics of your design and what you’re trying to accomplish. If you need text to flow around an element then a float is the obvious answer. If you need to center the element, inline-block is the better option.

Your choice will ultimately come down to the differences between floats and inline-blocks and which characteristics of each you need.

  • Use inline-blocks — when you need more control over the vertical alignment or horizontal positioning of elements.
  • Use floats — when you need other elements to flow around an element, support older versions of IE, or don’t want to deal with the horizontal whitespace issue.
Floated blocks in a grid
The blocks above have been floated left to create a grid. Block 5 gets trapped behind block 2 because block 2 has the greatest height in its row. This is a common issue when creating a grid of images.

Floats, Inline-Blocks, and Image Grids

In my case the use of inline-blocks is to help with the vertical alignment issue. I think this is the same for many people who’ve started using them. I’ve built several sites for photographers of late and naturally those sites inevitably have grids of images all over the place.

Floats work well if all the images in the grid are the same height. As soon as they aren’t, which is most of the time, floats get hung up behind whichever image in a row is tallest. This is because they are removed from the normal document flow.

Inline-blocks don’t have this issue, since they remain in the document flow. When it’s time for a new row of images they automatically clear the entire row above. In order to have the floated elements clear we’d need to specifically know which element needs to be cleared, which causes problems when things are created dynamically.

Using inline-blocks will typically make more sense here.

I’ve built a simple demo to illustrate the issue above and the different results when using floats and inline-blocks.

inline-blocks in a grid
The blocks above have been set to display as inline-blocks. Since they aren’t removed from the document flow, no block gets trapped behind another in the row above.

Inline-Blocks in Navigation

Another potential place you might choose inline-block is in horizontal navigation bars. We typically float the links and then set them as block level elements. I also find myself setting the list-items inline. If there’s a lot of switching inline and block values to work with floats, maybe a better solution is to use inline-blocks instead.

Any place you want elements in a row or over several rows you might want to consider using inline-blocks as opposed to floats. Of course, a table will also work in these circumstances. They are for aligning things in rows and columns after all.

If you’re building something more complex with rows and columns then a table (whether html or css) might be your best option, but when it’s something simple think of inline-blocks.

Vintage wooden block

Summary

We make great use of floats in our layouts, but are they always the tool we should reach for? Sometimes inline-blocks will be the better choice, especially if your goal is to lay out blocks in rows, like a grid of images or a horizontal list of links.

Inline-block elements take on the characteristics of inline elements from the outside and block level elements on the inside. This makes them very similar to floated elements, with a few key differences.

These differences are what will suggest which is more appropriate to use. If you’re having an issue with vertical alignment or horizontal position, you probably want to use an inline-block. If you need more control over a single element and how other elements react to it, you probably want a float.

And of course, a table (html or css) might end up being your best option depending on what you’re trying to accomplish.

Again this isn’t anything new, but I thought I’d give it a post and demo for anyone who like me, hasn’t been making use of inline-blocks where we should.

Download a free sample from my book, Design Fundamentals.

44 comments

  1. Perhaps this might be the solution to my problem on how to vertically align text in a nav – menu that needs to be responsive. I used a Chris Coyier responsive navigation bar technique which I found worked great for all single word menu items. Mine, however, varied between 1 and three words so the item changed height as window got smaller and the text vertical alignment was problematic.

    So, solved the issue by using ‘display: table’ which worked great UNTIL it needed to be responsive! So tables seem not to work well with @media queries in responsive designs.

    Don’t know how I’ll do it; but, perhaps some careful kloodging with widths and inline-block might get me closer. Has anyone already solved this problem who’d like to share?

    • Is the issue with a vertical menu of links? It sounds like as space gets smaller the extra words want to sit one of top of each other. Is that the problem?

      Or is it a horizontal menu, but at times the words break to a new line causing the menu item to be double the height?

      If it’s the latter you could add a non-breaking space between words. I’ll keep the height consistent, though it will also prevent the menu item from getting smaller than a certain amount.

  2. My personal approach to avoiding inline-block whitespace issues is

    item 1item 2

    Which keeps your code readable and can be stripped out of your page by some preprocessing to remove the quote entirely on the live server

  3. Very nice article, well explained. Thanks.

    The gap between inline elements is, as you suggest, a space character. The width depends on the font (family, variant, etc.) and approximates to .25em as you say. The negative margin fix is usually good enough, but not “pixel perfect.” The “font-size: 0;” does not work on all browsers if a minimum font-size is set. :(

    Might be worth mentioning that elements that have “layout” in old IE behave like inline-block if they are inline, or set to display inline.

    • Thanks David. So .25em is right then? I thought is was, but couldn’t find anything to corroborate.

      Good to know about the font-size: 0 method. I hadn’t considered about the minimums we can set on browsers.

      How old in IE are we talking?

  4. Definitely just realized I should have used inline-block instead of floats on an A-Z site index on a project I did a few months ago. It had always bugged me how things didn’t like up quite right when there was a long title. I use inline-blocks quite a bit, but the light never clicked on for this specific problem until I saw your photo grid diagram. I think I even used inline-block on the photo gallery on that specific project *facepalm*

    • Don’t feel too bad Greg. I did the same thing, turning to floats where I should have gone with inline-blocks. I had to do the facepalm too before I finally figured it out.

      On the bright side we both now know for the future.

  5. One gotcha to watch out for is when floating elements inside a container. If the element widths aren’t explicitly defined (with the exception of images) and if there are multiple rows of elements, then IE7 may wrap the text in the last element of each row in an effort to squeeze it in. Modern browsers will drop the entire element to the next row as expected.

    This surprising behavior is best described by an example. Compare this fiddle in IE7 and a modern browser: http://jsfiddle.net/vNZZ9/

    The solution is simple: explicitly define the element width(s), or—if the widths are unknown/dependent on the content—make them inline-block.

    • Nice catch Mike. I wasn’t aware of the the IE7 issue where it’ll wrap the text on the last element in the row. Hopefully it’s something we won’t have to worry about much longer as IE7 use continues to decline.

      Defining the widths of the elements should be a relatively easy fix too. Thanks.

  6. In my self-effacing opinion, inline-block property is unnecessary, because no renders the same in all browsers, because each browser does it his way, I like to write a simple code and clever, inline-block forces you to be writing more without necessity, if one understands well the behavior of each property, as the floats and the elements contained within the same element, need not be writing different code for severals browsers.
    Summarizing, hate finding codes with inline-block.
    :)
    A greeting!

    • I’m ‘fun’ of inline-blocks.
      They solve problem with collapsing layout when elements in row have different heights. They can also be very easy centered what is for me really great. I especially use them in pagination links. White-space is a little ‘devil’, that is fact but for me this is a small price to pay for all advantages.

    • Other than IE6 and IE7 I’m not sure what browser difference you’re referring to.

      I don’t think inline-blocks are something you would use for everything, but there are definitely times when they make more sense than using floats. They share many characteristics, but differ in a few ways that makes each a better choice under different circumstances.

  7. Nice post. I’ve been using inline-blocks more often too.
    I’d insist on using inline-block on inline elements, not blocks, to work in IE.
    By default use spans instead of divs.

    • Is that for all versions of IE or just older versions like 6 and 7?

      What’s the rationale for using inline elements as opposed to block level elements? I would think once you set the element to inline-block it wouldn’t matter what the original display value was.

      • That’s up to IE7, you can test here: http://jsfiddle.net/DzBgB/2/

        I didn’t remember which version, but took the habit since my company still supports IE7 for its clients.
        That’s nothing to do, but if you don’t your layout ends up totally broken in IE7, and unfortunately there are still people using it… It depends on your public.

  8. The known CSS trick for making inline-block work in IE7 is:

    .block {
    display: inline-block;
    *display: inline;
    zoom: 1;
    }

    Didn’t test is though. Anyone knows if it works as expected?

    Another thing to keep into consideration is that IE7 does not support box-sizing: border-box, so applying padding or borders directly on the inline-block elements would break the layout.

    • Thanks. Good to know for those times you can’t use an inline element. Not that I’m seeing you mention this it does seem like a familiar hack. I just did a little searching and see this fix all over the place. I’ll assume it works even though I haven’t tested it either.

      Good point about box-sizing, etc. Another thing I hadn’t considered.

    • Thanks Brett. Nice find. I looked through the comments on the CSS Tricks post, but must have missed that solution.

      It’s an easy fix too and I agree it seems better than the other solutions, which I’m not crazy about.

      My one question would be if you’re setting the parent to display as a table, why not then set the children to display as table cells? Maybe it’s something worth a deeper look to assess the pros and cons of each.

    • Thanks Matt. I hadn’t realized that. I updated the post to mention it and point to your test cases.

      I’ve been using the display: table added to the container trick that Brett mentioned above.

  9. While IE8 does solve quite a lot of inline-block issues that IE7 had, it’s still not completely bulletproof. Once example is this : http://www.css-lab.com/demos/nav/inline-block-ie8.html. And there are more.

    I haven’t used inline-block for quite a while now, and I probably won’t for quite some time. Even if our company starts to offer IE9+ only support ( instead of IE8+ ), I probably still won’t use it.
    I’m used to fixing everything with floats, and a decent clearfix class ( and not the extra div after the last floating element with clear:both added to it ). I’ve found it to have a much better X-browser support, and I haven’t come across a problem I couldn’t fix.

    True, some things are a bit trickier ( e.g. the grid, though you can add a wrapper around each row ). But all in all, I save more time & frustration on all other things combined, then what I lose in time on the grid structures.

    And to be honest, things like negative margin, writing everything line or setting font-size to 0 are not solutions I will ever use.
    Negative margins are – as mentioned – not font consistent. Writing everything inline goes against structure, and setting the font-size to 0 to hide a space .. well, that just sounds wrong. At least to me.

    Funny actually, because this discussion actually arises almost weekly in the office :)

    • Thanks for the link Justin. I hadn’t seen that before. I know inline blocks aren’t a perfect solution, but they do seem appropriate in certain cases. Sometimes the space between elements isn’t a big deal.

      The problem I find with clearfix or a wrapper around floats comes in with responsive design. Say the gird needs to be 4 columns at one size and 3 columns at another, the wrapper or clearfix breaks things on one or the other where you don’t necessarily want. That’s where I’ve found inline blocks to be beneficial.

      I wouldn’t use them for everything, but I think they’re a workable solution for certain things. I’ve been using the css table trick Brett mention above.

  10. Thank you so much for this post! It really helped me visually see the differences, and it helped me very much. Please keep up the good work!

Leave a Reply

Your email address will not be published.

css.php