Phantom Spacing On Inline-Block Elements

This was a hard problem to solve the first time I ran across it. Until flexbox gains better support, front-end developers have a couple of simple ways to align block elements side-by-side, each with its own distinct problems. You can float elements but then you have to worry about clearfix on parent elements. It may seem simpler to use display: inline-block instead.

Although that does mean you can leave off the clearfix, it also comes with a problem of its own. If you write good, readable HTML with indentation to show nesting of elements, inline-block is going to cause you some heartache. If you like me, you’ll start looking for some padding or margins you hadn’t accounted for, but the real culprit is much more difficult to find if you don’t know where to look.

Setting display to inline-block is going to effectively turn your block elements into inline elements. Let’s imagine I have a couple of divs with this display property set. Here’s my code:

<div>
     <p>Some content</p>
</div>
<div>
    <p>More content</p>
</div>

So, I have two inline elements amply spaced to make my code readable. Let’s think about this in terms of text, the most ubiquitous inline element. What happens to white space between two inline elements like characters of text? The whitespace between them is collapsed down to a single character. That means this:

<p>Today,
I had
a
root    beer
        float.</p>

will render as this:

Today, I had a root beer float

The same rules apply to our once-block-now-inline elements. We put in tabs and newlines thinking that’s just for us and the browser won’t care. While that’s true for true block elements, it’s no longer the case for inline elements. The browser inserts a single space between the elements and ignores the remaining newlines, spaces, and tabs we’ve used.

I built a pen on CodePen to demonstrate this and the havoc it can wreak on your layout.

You could always get around this and still use display: inline-block by cramming everything together, but who wants to read that code after the fact?

<div><p>Some content</p></div><div><p>More content</p></div>

My recommendation is that you instead use floats for the time being and hope for the day when flexbox comes to save us all from our element positioning nightmare!