A great big welcome to inline-block!

One of the really great things about Firefox 3 is that it includes support for the CSS display:inline-block attribute! This means we actually can start using the attribute because that all modern browsers (IE7 included) have support for it.

Inline-block is a halfway point between setting an element’s display to inline or to block. It keeps the element in the inline flow of the document like display:inline does, but you can manipulate the element’s box attributes (width, height and vertical margins) like you can with display:block.

Here’s a simple example that shows the difference between an element with it’s display set to inline and one set to inline-block:

  1. .inline-block
  2. {
  3.     display: inline-block;
  4.     background-color: yellow;
  5.     border: 1px black solid;
  6.  
  7.     height: 35px;
  8.     margin-top: 20px;
  9.     margin-bottom: 20px;
  10. }
  11. .inline
  12. {
  13.     display: inline;
  14.     background-color: lime;
  15.     border: 1px black solid;
  16.  
  17.     height: 35px;
  18.     margin-top: 20px;
  19.     margin-bottom: 20px;
  20. }

The green inline span ignores the height and vertical margins set on it. The yellow inline-block span obeys them which affects the size of the box and the line height but doesn’t stop the span being in the inline flow of the document:
you can set width and height on an inline-block element but not on an inline one

So why is this a big deal?

The biggest reason this is exciting is it means you can now do some simple page layout without needing to use floats or absolute positioning.

Use inline-block to line things up without using floats

Using inline-block we can line items up next to each other without using floats. My favourite example of this is the astoundingly frustrating task of creating a tabular form. Imagine you have a stupidly simple form where you have one label next to one input item (here’s another approach for more realistic forms):

  1. <fieldset>
  2.     <legend>Comment form</legend>
  3.  
  4.     <label for="name">Name:</label>
  5.     <input type="text" id="name"/><br />
  6.  
  7.     <label for="email">Email:</label>
  8.     <input type="text" id="email"/><br />
  9.  
  10.     <label for="comment">Comment:</label>
  11.     <textarea id="comment"></textarea><br />
  12. </fieldset>

To make the form elements line up you just need to set a width on the label. No floats are needed so you don’t need to worry about clearing or overflow:auto or any of the issues that make floats a bit of a pain to use:

  1. label
  2. {
  3.     display: inline-block;
  4.     width: 100px;
  5.     vertical-align: top;
  6.     …
  7. }

Complete example

tabular form

Align elements using text-align and vertical-align

Elements using inline-block can be horizontally and vertically aligned using the text-align and vertical-align attributes.

This is a big advantage of using inline-block instead of floats. With floats you can only really vertically align a box to the top of the other boxes it is next to. With inline-block, you can use any of the vertical align attributes:

Complete example

There’s a really nice example of using this to create a grid of images.

A small gotcha – spaces between the elements

If you’re used to the way block elements line up next to each other, there’s one thing about inline-block elements that might surprise you. Inline-block elements are still part of the inline flow of the document so if there is a space between the items, there will be a space between the boxes.

So markup like this:

  1. <div id="nav">
  2.     <a href="/">Home</a>
  3.     <a href="/">Swizzlesticks</a>
  4.     <a href="/">Widgets</a>
  5.     <a href="/">Acme products</a>
  6.     <a href="/">Specials</a>
  7.     <a href="/">Contact us</a>
  8. </div>

Would produce elements that look like this:
a space between each element

There’s a kind of nasty hack to get around this. You can set the parent container’s font-size to 0 and then reset it to whatever you need for the child elements. I think if you need to do that, you should probably just use block elements and floats.

Who supports it

Now that Firefox 3 supports inline-block, it has pretty good browser support.

IE – it’s supported completely in IE8. IE7 only support inline-block on elements that are usually inline (like spans and anchor tags). IE6’s implementation is pretty flaky.

Firefox – it’s supported in Firefox 3 and above.

Webkit – it’s supported in Safari 3 and above. It’s supported in all versions of Chrome.

Opera – it’s supported in Opera9 and above (I’m not sure about earlier versions).

Check out the quirks mode compatibility charts for more information. There’s also a great article about gotchas getting it working across browsers.

Workarounds for IE6 and IE7

In IE6 and IE7 you can only apply inline-block to inline elements. You can’t apply it to block elements.

Fortunately this is pretty easy to work around because in IE6 and IE7 the display:inline actually acts like inline-block. It supports applying attributes like width and height on both inline and block elements, not just block elements like in other browsers.

I wouldn’t really recommend using inline-block at all in IE6 because it seems generally flaky. The inline-block elements don’t seem to sit in the right place in the line. Here’s how my earlier example looks in IE6:
inline-block elements don't sit in the right place on the line

Workarounds for Firefox 2

There are a few similar display values that might be useful if you need to support earlier versions of Firefox, but none of them do exactly what inline-block does.

  • -moz-inline-block – this seems to be an experiemental version of inline-block. It’s now obsolete. I always found it to be buggy.
  • -moz-inline-box – doesn’t wrap to a second line.
  • -moz-inline-stack – this is supposed to be used for XUL rather than pages. It doesn’t have the wrapping problem that -moz-inline-box has but has other issues of its own.
Posted on 09 Aug 09 by Helen Emerson (last updated on 20 Mar 13).
Filed under CSS