Using Inline-Block and Word-Spacing to Make Columns Easier
Posted by Kyle Weems on March 23, 2009Columns or grids, whatever you’re calling your blocks of content that are stacked next to each other, you’ve often got an annoyance when working on a design. I’ve probably covered this topic something like six million times, as I for one am easily annoyed by unnecessary floats, but historically found myself using them way too much to make some sort of grid of blocks work out to make a designer’s dream a reality.
I don’t know why floats drive me bonkers. But they do. I feel like frequently they’re being used almost exclusively to solve problems that were never intended for them, and the end results can get messy as soon as a client starts using a carefully balanced page built upon delicate floats and adds an unexpected list or makes a given element too full or too empty.
Not terribly far back in the past I talked about display: inline-block, one of my favorite CSS style, as a solution to this problem at Mindfly in The Curious Case of Inline-Block. It provides a nice tutorial to getting columns of content to work side-by-side without floats using inline-block, and how thanks to the quick adoption rate of Firefox 3, all major browsers (including IE6) support this style (granted, IE6 & 7 actually require a helping hand, but the tutorial discusses the easy fix).
I had one problem that nagged at me, though. Whitespace. In particular, the inline-block style is whitespace sensitive, so normal markup practice will result in your columns getting space between them when you use this style, which can mess with your carefully measured columns, and so forth. One possible fix is to simply remove any whitespace between the elements in question, but this is impractical for two reasons: 1. A lot of dynamically generated content won’t be set up with that sort of issue in mind, and 2. Clients entering their own content.
So I did some digging around, and through a complete accident later stumbled upon word-spacing, a style I’ve never had cause to make use of in the past. It’s simple enough as a style goes. Give it a value (in px, em, etc) and that’s how it modifies the existing whitespace between words. This counts for space between inline-block elements as well. So if you give the parent of those elements word-spacing: -1em, then it will remove the whitespace (normally 1em) that is between your inline-block elements. The catch? Make sure to give the elements themselves word-spacing: normal to resest the spacing for any text inside them, or you’ll get some nasty results.
Here is an example of positioning items side-by-side cleanly by using word-spacing and inline-block together (as well as showing the IE6&7 fix). Of course, with the whitespace issue solved, you can add your own margins to elements to create whatever nice gutters and such that you prefer.
Tags: CSS, inline-block, trick, word-spacing
Stumbled on this page ‘cuz a buddy linked it to show the cool dhtml parallax effect you did in your header. Very nice!
Regarding the inline-block discussion though, your example page doesn’t look quite right in Chrome and Safari 3 (for Windows). The 3rd and 4th examples are retaining their 1 em word-spacing for some reason. Just thought you should know.
@Alex – You’re absolutely right. It doesn’t work in those. I figured that out after this post, and address the issue here: http://www.cssquirrel.com/2009/04/09/word-spacing-and-inline-block-incompatibility-in-webkit-browsers/. In the comments a reader came up with a fairly good solution, so feel free to check that out.
Thanks for the compliment regarding the parallax!
I got this to work in safari by using the same method but ‘letter-spacing:-1em’ instead of word spacing.
This does not work since you cannot know what the default word- or letter-spacing is. I tried rendering 3 blocks of fixed size in Safari and Chrome as inline-block list items, first with no whitespace between the tags, and then with your technique (I tried both word- and letter-spacing). The combined width of the blocks in the second case was several pixels less than in the first case. I think the only approaches which work are to either eliminate all whitespace between tags, or to declare “font-size: 0″ (which is very difficult in practice since it requires you to know what the current font size is so you can restore it in the child).
@Senderista
“font-size:0″, that’s simply genius. I was pondering about that white-space problem with inline-block for a while and didn’t come up with a satisfying answer until I read your comment. Now seeing that solution, it is so simple, how couldn’t I ever thought about it. I really have no problem with restoring the font-size to the child elements, it’s simple as “font-size:12px” for example, as I usually work in pixels. One more trick to add in my CSS magician’s pocket ! Thank you !