inline-block: The complete story

inline-block is something I hadn’t used until a couple of months ago. I was comfortable with block and inline elements so I didn’t feel the need to learn anything more. I was also under the impression, as I’m sure many developers are, that anything other than display: block and display: inline has cross-browser inconsistency problems and should be avoided.

This article focuses on why you should start using display: inline-block, understanding this value as well as how to make sure it is consistent across all modern browsers and IE7+.

Note: If you don’t yet know the differences between inline and block level elements, check out what css-101 has to say about it.

inline-block is your missing friend

inline-block solves all sorts of problems web-devs run into on a daily basis. I’m going to go through various common scenarios and cover how I would deal with them in a cross-browser fashion. You may notice some odd/hacky CSS included in the following examples – this will be covered in the Browser Compatibility section later in the article.

inline-block vertically center (IBVC) hack

Chris Coyier talks about a “Ghost” IBVC method and he credits Michal Czernow for it’s origin. Chris also mentions how it’s equivalent to the display: table/table-cell method since it also doesn’t support IE7. I’ve been playing around with inline-block and tinkering with vertical centering and I’ve come up with something that seems to be the ‘Ghost’ method (I’d discovered the ‘Ghost’ method after stumbling upon this solution) with a few differences. The two differences being mine supports IE6+ (not that IE6 matters at all anymore, just an FYI) and it doesn’t require pseudo elements to function.

Being able to vertically center an element with a dynamic height is something that has plagued developers (or me at least) for a very long time and the cross-browser solution has been somewhat of a holy grail. I’ve seen many different vertical centering methods, the most popular being the display: table used with display: table-cell. The problem with this is IE7 doesn’t support either of those display values.


I feel this hack is a more simple and easily understandable way of vertically/horizontally centering an element than the previously mentioned table/table-cell/IE7-bug-hack method. I also feel it’s much easier to understand and work with than the Gary Turner method too, but well done to him for coming up with that over 7 years ago. I’m sure other people will feel differently about this being the “best” way, however this is what I prefer..

Problems

 

vertical-align property

One slight downside to this I’ve noticed is vertical-align: middle vertically aligns the capital letters, so lower case letters or inline-block elements are very slightly off center. I’ve noticed elements being off by about 2px to 4px depending on what size the items are. Although this occurs it’s pretty much negligible for me – especially since I can’t actually notice this unless I actually count pixels.

Space characters

Space characters are handled like a space would be handled within inline-elements. This means that spaces and or tabs will be displayed as a space once the page has rendered. There are a couple of ways to work around this problem but it can be annoying nonetheless.

IE7 hand-holding

The above mentioned ‘space characters’ problem doesn’t take affect in IE7. The problem IE7 does come with is that it requires at least 1 other inline-block element to be present to allow the inline-block to vertically center. To get around this, I’ve added an “invisible” element after the item I’m centering – I’ve added it afterwards incase :first-child is used. This was included in the Ghost method through pseudo elements. Even though I’ve managed to remove pseudo elements, I’ve had to add an equivalent (or worse since it’s actual markup) for IE7. Boo.

Alternative methods

There is an IE7 CSS bug in which you can center an element vertically, and if used along side the table/table-cell method, it can work nicely (However I haven’t used it in practice). This can also be done using the Flexbox layout module – Flexbox is definitely something that will be used much more in future, however as Le Roux pointed out to me, the current Flexbox support right now is a bit flakey – So it may be another 1 or 2 years before we can start using it with absolute confidence.

Centering navigation items

I often come across a navigation design where the amount of items in the navigation should be dynamic, however the navigation itself should remain centered regardless of how many or how wide the items are. Previously I would have centered this with display: table, however, since display: table doesn’t have any IE7 support, I would have probably also used an IE7 javascript fallback (Or just let the navigation appear left aligned in IE7). With display: inline-block, this same result can be achieved with 2 (or 4 including IE7 support) css properties and values.


How simple was that? Seriously?

Article block listings

Generally I solve the following kind of problem differently depending on the exact design and how I feel at the time.

article listing example

An easy inline-block solution would be:


The design could have been more tricky, though. Typically the height would be dynamic, or possibly both the height and width. As you can see this isn’t exactly a masonry layout since each row starts and ends at the same top-offset. It is still not possible to solve a masonry design in LTE IE9 without javascript. The height of these items are dynamic though, mere floats wouldn’t work correctly. If we used floats would end up with something like this:


To avoid that we could use :nth-child and detect the first item in each row and then clear: left, but that would pose some cross-browser problems itself since :nth-child is only supported by modern browsers. We could add classes to these items via the CMS/backend language, but it would be easier if we could just get this working with CSS alone and without any problems! :(
Yay, inline-block the the rescue again! :D You didn’t expect that did you?!


 

More navigation

Surely there is some limit to the IE7 support? What about an inline-block within an inline-block?!


In the above example I have 3 levels of nested inline-block items and it works perfectly in IE7+.

Browser compatibility

If you’ve read up until this point, you are well aware that an IE7 hack should be used to “enable” the inline-block functionality.

The IE7 hack

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

This could be turned into valid CSS if you are using the <html> conditional classes (included in h5bp):

.item { display: inline-block; }
.lt-ie8 .item { display: inline; zoom: 1; }

Why does that work?

IE7 doesn’t support inline-block per se, however you can mimic the functionality by making it be an inline element and triggering hasLayout on the element. The zoom: 1 visually doesn’t change anything. It is applied this way because it is one of the properties that triggers hasLayout.

Conclusion

inline-block is an amazing and underrated and underused property, in my opinion. inline-block is something that can and should be used today with confidence. We fear that which we do not understand – hopefully inline-block is now added to your CSS toolbox.

What say you?

  1. frontend-er says:

    Hi, great write up, however your solution doesn’t work in IE7

    1. Jamy Golden says:

      Thanks. I’ve checked the examples in IE7 and they do work. Which one are you having a problem with?