132

Normally, when we want to have multiple DIVs in a row we would use float: left, but now I discovered the trick of display:inline-block

Example link here. It seems to me that display:inline-block is a better way to align DIVs in a row, but are there any drawbacks? Why is this approach less popular then the float trick?

XML
  • 19,206
  • 9
  • 64
  • 65
Ryan
  • 10,041
  • 27
  • 91
  • 156

5 Answers5

161

In 3 words: inline-block is better.

Inline Block

The only drawback to the display: inline-block approach is that in IE7 and below an element can only be displayed inline-block if it was already inline by default. What this means is that instead of using a <div> element you have to use a <span> element. It's not really a huge drawback at all because semantically a <div> is for dividing the page while a <span> is just for covering a span of a page, so there's not a huge semantic difference. A huge benefit of display:inline-block is that when other developers are maintaining your code at a later point, it is much more obvious what display:inline-block and text-align:right is trying to accomplish than a float:left or float:right statement. My favorite benefit of the inline-block approach is that it's easy to use vertical-align: middle, line-height and text-align: center to perfectly center the elements, in a way that is intuitive. I found a great blog post on how to implement cross-browser inline-block, on the Mozilla blog. Here is the browser compatibility.

Float

The reason that using the float method is not suited for layout of your page is because the float CSS property was originally intended only to have text wrap around an image (magazine style) and is, by design, not best suited for general page layout purposes. When changing floated elements later, sometimes you will have positioning issues because they are not in the page flow. Another disadvantage is that it generally requires a clearfix otherwise it may break aspects of the page. The clearfix requires adding an element after the floated elements to stop their parent from collapsing around them which crosses the semantic line between separating style from content and is thus an anti-pattern in web development.

Any white space problems mentioned in the link above could easily be fixed with the white-space CSS property.

Edit:

SitePoint is a very credible source for web design advice and they seem to have the same opinion that I do:

If you’re new to CSS layouts, you’d be forgiven for thinking that using CSS floats in imaginative ways is the height of skill. If you have consumed as many CSS layout tutorials as you can find, you might suppose that mastering floats is a rite of passage. You’ll be dazzled by the ingenuity, astounded by the complexity, and you’ll gain a sense of achievement when you finally understand how floats work.

Don’t be fooled. You’re being brainwashed.

http://www.sitepoint.com/give-floats-the-flick-in-css-layouts/

2015 Update - Flexbox is a good alternative for modern browsers:

.container {
  display: flex; /* or inline-flex */
}

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

More info

Dec 21, 2016 Update

Bootstrap 4 is removing support for IE9, and thus is getting rid of floats from rows and going full Flexbox.

Pull request #21389

Community
  • 1
  • 1
Alex W
  • 37,233
  • 13
  • 109
  • 109
  • It's worth noting that the article you linked shows two different ways of *not* requiring additional, non-semantic markup to accomplish clearfix. – Tim M. Mar 02 '13 at 18:32
  • Noted. However, the clear fix will not allow two floated containers to appear next to each other, which is also mentioned in the article. Clear fix is inherently a "fix." You only need a fix when something is broken or incorrect. – Alex W Mar 02 '13 at 18:36
  • 4
    "clearfix" is just a name; the "fix" indicates fixing of incorrect expectations and/or incorrect browser implementation. I (happily) agree that there are alternatives to floating/clearing, but there is nothing inherently broken *or* fixed about it. – Tim M. Mar 02 '13 at 18:47
  • The incorrect expectations are a result of using `float` for something it was not intended for: http://css-tricks.com/all-about-floats/. Besides, why add the extra trouble of having to clear every float? I have maintained other developers' float layouts, and when the CSS changes or the CMS doesn't put a clear fix somewhere it wreaks havoc. – Alex W Mar 02 '13 at 18:55
  • 1) The only point I was trying to make is that there is nearly always a way to achieve the the desired float layout behavior without any extra, non-semantic elements. 2) Yes, float layouts can be hard to maintain. There is often an easier alternative. *This is a good thing, no argument.* 3) CSS Tricks is not the [spec](http://www.w3.org/TR/CSS21/visuren.html#floats), which merely says "A float is a box that is shifted to the left or right on the current line." Drafts from years earlier state the same, and the most current CSS3 drafts do not say that floating is only for text/images. – Tim M. Mar 02 '13 at 19:07
  • 10
    @Alex - Is there a non-hacky, cross-browser-compatible way to remove the whitespace between inline-block elements that are on separate lines? I would like to be able to stop using floats but the best links I could find about this problem ([here](http://css-tricks.com/fighting-the-space-between-inline-block-elements/) and [here](http://stackoverflow.com/questions/2628050/ignore-whitespace-in-html?rq=1)) are unsatisfactory. You mention the `white-space` property -- could you explain this? – antinome Nov 15 '13 at 17:05
  • @antinome Have you tried setting `font-size` to `0` on the white space ? That should work cross browser. Also, `white-space: pre-line` [will collapse the white space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space). – Alex W Nov 15 '13 at 17:10
  • @Alex: `pre-line` doesn't seem to work - [here's my jsfiddle](http://jsfiddle.net/PEcHf/). And `font-size:0` is, IMHO, a worse hack than the modern clearfix - you then have to reset the font size to it's original value on the `inline-block` element, which is hard to maintain. – antinome Nov 15 '13 at 17:29
  • I just realized I was not very clear about what I want. I would like the inline-block elements to be on separate lines _in the markup_ but to appear side-by-side in the browser (without any gap between them). – antinome Nov 15 '13 at 17:49
  • @antinome For your case I would use `nowrap` because `pre-line` honors line breaks, which I assume you don't want. The only [white space that is left](http://css-tricks.com/fighting-the-space-between-inline-block-elements/) is from the browser's letter spacing because it's essentially treating your divs as letters. So you can just set left and right margins to `-2px`: http://jsfiddle.net/PEcHf/1/ to offset the `letter-spacing` – Alex W Nov 15 '13 at 17:49
  • 3
    @Alex - thanks, that is very cool, but I still find the float-with-modern-clearfix approach a bit more maintainable, because it won't break if I someday happen to customize `letter-spacing` elsewhere in my CSS. – antinome Nov 15 '13 at 17:59
  • 1
    why does the bootstrap is still using float for its grid system ? Aren't those are layout ? – AzDesign Feb 18 '14 at 15:17
  • 1
    @AzDesign My guess is, because novice Bootstrap users wouldn't be happy if they couldn't use the grid system on `
    ` elements, since it would cause issues in older versions of IE if it used inline-block instead of float. So, basically, for older browser compatibility.
    – Alex W Feb 18 '14 at 16:21
  • I know I'm being pedantic, but vertical-align:middle doesn't *perfectly* vertically align an inline block element. It aligns it to the middle of the lowercase letters that would exist in the generated line box. That is not the same thing. – Jimmy Breck-McKye Mar 10 '14 at 21:13
  • I will now go over to inline-block. But, just to correct; - clearfix is not needed if all parents also are floating! – Peter Westerlund May 21 '14 at 07:34
  • 2
    Keep in mind that inline-block adds white space around elements. If you are using it for a grid, or don't want this white space, you will have to add extra styling/HTML hacks to account for this. See: http://css-tricks.com/fighting-the-space-between-inline-block-elements/#comment-166444 – kretzm Sep 10 '14 at 15:06
  • The argument could be made that that's 4 words }:D – Gershom Maes Nov 20 '15 at 21:53
  • So, why bootstrap grid uses float left instead of inline-block ? – Dmitry Yaremenko Jan 29 '17 at 13:09
  • But to use `vertical-align: middle` you can always choose to `display:table-cell` and parent as `display:table` – Tilak Madichetti May 30 '20 at 09:05
25

While I agree that in general inline-block is better, there's one extra thing to take into account if you're using percentage widths to create a responsive grid (or if you want pixel-perfect widths):

If you're using inline-block for grids that total 100% or near to 100% width, you need to make sure your HTML markup contains no white space between columns.

With floats, this is not something you need to worry about - the columns float over any whitespace or other content between columns. This question's answers have some good tips on ways to remove HTML whitespace without making your code ugly.

If for any reason you can't control the HTML markup (e.g. a restrictive CMS), you can try the tricks described here, or you might need to compromise and use floats instead of inline-block. There are also ugly CSS tricks that should only be used in extreme circumstances, like font-size:0; on the column container then reapply font size within each column.

For example:

Community
  • 1
  • 1
user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125
  • is there any possible workaround for the no-whitespace-between, maybe `div+(whitespace) {display:none}` or something? – NoBugs Jun 03 '15 at 15:01
  • 1
    See the third paragraph after its first sentence... Particularly see the linked question – user56reinstatemonica8 Jun 03 '15 at 15:07
  • @NoBugs simply apply font-size: 0; to the containing element, just watch out if you dnt have specific font sizes set on elements within the inline-blocks!! – Jai Sep 16 '15 at 12:17
  • @Jai Exactly, and since styling/view should be disjoint from the process creating the html/model, that is a bad practice. (What if you use a service that gave you `
    hi
    there
    more content here... ` ?)
    – NoBugs Sep 17 '15 at 03:51
4

If you want to align the div with pixel accurate, then use float. inline-block seems to always requires you to chop off a few pixels (at least in IE)

Rajesh Loganathan
  • 11,129
  • 4
  • 78
  • 90
Vins
  • 49
  • 1
  • 6
    Yeah that's because you have to avoid using spaces between elements because inline-blocks take into account spaces the same way as inline elements. Keep inline-block tags tight to each other and no problems with pixels. – pronebird Feb 28 '14 at 16:18
  • Also this can be a browser difference with default padding/margin on elements.. Well at least in the past i have always done `* {padding:0px; margin:0px; }` as this helps balance my coding – Angry 84 Apr 15 '15 at 08:30
  • Is this the reason Bootstrap (maybe others) use it rather than inline-block I wonder? – NoBugs Jun 03 '15 at 15:02
2

You can find answer in depth here.

But in general with float you need to be aware and take care of the surrounding elements and inline-block simple way to line elements.

Thanks

atiquratik
  • 1,296
  • 3
  • 27
  • 34
abhijit
  • 1,958
  • 3
  • 28
  • 39
1

There is one characteristic about inline-block which may not be straight-forward though. That is that the default value for vertical-align in CSS is baseline. This may cause some unexpected alignment behavior. Look at this article.

http://www.brunildo.org/test/inline-block.html

Instead, when you do a float:left, the divs are independent of each other and you can align them using margin easily.

Sydney
  • 1,349
  • 1
  • 14
  • 20