Ever since the web standard movement convinced web designers to move away from tables towards proper semantic markup, we've constantly struggled with a seemingly simple task: lining elements up horizontally next to each other.
Somewhere in the far future, probably after the creation of the neuro-web that I predict in this CSSquirrel comic comes to existence, browsers will finally start implementing the Advanced Layout Module.This amazing piece of CSS3 will make it so simple to stack elements in any order that it'll make you feel like you're rooting around with dirty tables in the mud again, but this time in a completely semantically-neutral, web standards way.
However, that utopian future is dismally far away, leaving us with the original problem: lining up block elements next to each other.
You would think that this would be an easy enough thing to accomplish. After all, bricks can do it:
Artwork can do it:
And even ducklings can do it!
But for web desigers, though, it's an incredibly difficult thing to do without generating more problems, especially with CSS.
A common solution is to use float:left to float block-level elements next to each other. This creates a number of headaches, though, usually involving float behavior that isn't predicted or having to clear the floats to keep the elements tucked inside their parents. I've found myself often guilty of creating incredibly complex markup and style structures to keep things in place, only to later find a bug cropping up when some additional content is added.
There's been a solution proposed for quite some time in CSS 2.1 – display: inline-block.
What is inline block? Well, according to the W3C definition it is "A block box, which itself
is flowed as a single inline box, similar to a replaced element.
The inside of an inline-block is formatted as a block box, and the
element itself is formatted as an inline replaced element."
In English, I'd say that it's a block-level element that flows inline, but retains all the width/height/margin qualities of a block-level element.
This means we can have our cake and eat it too, by giving an element all the dimension-setting qualities we enjoy while still stacking it side-by-side with another block of content. And all this without floats.
So why hasn't this always been in use? Simple, browser makers hate us.
Well, I don't know if they actually loathe our existence. But through their actions we can infer that they at least enjoy tormenting us. Firefox 2 (and prior) doesn't support inline-block at all, and Internet Explorer only supports it on inline elements (which is actually contrary to the situations we're going to most likely want to use it in).
However, there's a bright light that makes me say that from now on you should drop those floats (except where they're genuinely needed) and use inline-block for your everyday horizontally stacking needs. First, Firefox 3 has been out for some time and the conversion from 2 to 3 has been fairly rapid. Firefox 3 also supports inline-block. Secondly, not only is Internet Explorer 8 on the horizon with proper inline-block support, but we can trick IE 6 & 7 into doing what we want with only a little CSS voodoo.
By and large, there's nothing special that needs to be done beyond applying the display:inline-block style to the elements you want to flow next to one another. There's some considerations to take into account, though. First, elements with this style are whitespace sensitive, which means you'll have space betweent the blocks if you've got a space between the elements in your markup. Secondly, if you want the elements to line up on the top instead of the bottom you need to make sure they have the appropriate vertical-align style set.
Of course, for IE versions prior to 8 there will be issues. Namely that if you're using inline-block on a block element (which is usually the case) it won't work by default. However, there's a simple trick to making IE comply.
First, in your normal stylesheet do the usual display:inline-block declaration. Then, in an IE stylesheet that is conditionally called (for versions below 8) and that comes after your normal sheet, give that same element (or elements) the display: inline property. The elements will retain the block style, but will now also be inline, as desired.
The example shows this IE trick.
The last hurdle you might face is supporting Firefox 2. I'm of the opinion that the Firefox 2 userbase is so vanishingly small at this point that it's a non-issue. However, for the sake of sounding genuinely concerned about all users, here's a solution for that browser version:
- Give the element(s) display:-moz-inline-box; (yes, it's box not block)
- The content may spill out of the elements, so you may need to wrap them in other elements with the width set to hold the contents inside.
By adopting inline-block into our CSS vocabulary, we can jettison a lot of the baggage of complex float solutions for many seemingly simple designs. Sure, it's no Advanced Layout Module, but it's still a steady improvement.