Photograph of a set of child alphabet blocks

Previously I’ve discussed what I called “the two kinds of element”: inline and block. That was an oversimplification for the purpose of instruction: in reality, HTML elements can have over a dozen different display values.  inline and block were the first and simplest values added to the CSS spec. display: table and its related values are almost as old, while and grid are the latest. Somewhere in the middle is inline-block.

Using inline-block can solve many common frustrations and limitations in web design, although not without introducing a few of its own.

Perhaps the easiest way to understand the properties of these display values is to compare them side-by-side:

Inline Elements

Following the spec, inline elements only respect horizontal padding and margin values; margin-top and padding-top are ignored, as are margin-bottom and padding-bottom.

border can be applied to the left and right of inline elements, but border-top and border-bottom won’t work. The content of an inline element determines its size (padding-left and right aside), it cannot take explicit width or height values.

Block Elements

By default, a block element is the full width of its container, no matter how little content it has. A block element’s height is determined by its content, by default. Explicit and implicit widths and heights can be applied via CSS, as can padding, margin and border on all sides.

Block tags are “on their own line” by default: think of heading and paragraph elements. That means getting block elements lined up side by side on a web page can be tricky.

Inline-Block

inline-block is a hybrid of both display values: tags with inline-block can take explicit widths and heights, as well as border, margin and padding on all sides. However, inline-block elements remain inline; that is, they appear side-by-side with other inline or inline-block elements. For all intents and purposes, inline-block tags behave much like replaced elements, such as images.

Real-World Uses of Inline-Block

A good example of how inline-block can be used in modern web design is a simple site navigation bar:

<nav>
	<a href="#">Home</a>
	<a href="#">Products</a>
	<a href="#">About</a>
	<a href="#">Help</a>
</nav>

Applying the following CSS:

nav { 
	background: #222 url(debut_dark.png);
}
nav a {
	font-family: Proxima Nova, sans-serif;
	color: #fff;
	text-decoration: none;
	transition: .4s;
}
nav a:hover {
	background: rgba(255,0,0,0.5); 
}

The result will look like this:

Trying to get space between the links should be relatively easy:

nav a { padding: 1rem; }

This certainly spaces the links apart, but not in the way you might expect. Try hovering over the links in the example below:

You can see that the hover effect “slops over” the top and bottom edges of the <nav> bar. As inline elements, the links will take padding on the left and right; but padding on the top and bottom won’t contribute to the computed height of the elements.

There are ways around this: adding a calculated top and bottom padding to the <nav> element to balance out the changes will work, for example. But a far better and simpler solution is to alter the display quality of the links themselves:

nav a { 
	display: inline-block;
	padding: 1rem;
}

Now padding influences the links evenly on all sides, as one would expect:

Discontents

There is one downside of inline-block: it automatically inserts spaces between elements on the same line.

The fact that the browser inserts spaces actually makes a certain kind of sense: you would normally want spaces to appear between words. But in this case, it’s a really annoying behavior.

As always, Chris Coiyer has some excellent solutions to this issue. My personal favorite in this case is to remove the carriage returns in the HTML code, thus eliminating the spaces:

<nav>
<a href="#">Home</a><a href="#">Products</a><a href="#">About</a><a href="#">Help</a>
</nav>

This approach also has the very minor advantage of slightly reducing file size, as any bytes saved in your code mean faster downloads. An alternative and slightly trickier approach is to do the work of removing the spaces solely via CSS, “sucking out” the gaps by reducing font-size to 0 for the parent element:

nav { font-size: 0; }

Of course, this has to be countered by increasing the font-size of the child elements; otherwise, everything will be shrunk to infinity:

nav a { font-size: 1rem; }

You can use whatever technique you wish, although I would suggest trying them out and then sticking to one for the sake of consistency.

Combining Inline-Block With Flexbox

It’s worthwhile noting that inline-block can be handily associated with and other values of display. For example, after grouping three of the links in a <div> container:

<nav>
	<div>
		<a href="#">Home</a><a href="#">Products</a><a href="#">About</a>
	</div>
<a href="#">Help</a>
</nav>

…we can apply flexbox controls to the <nav> element to separate the first group from the “Help” link:

nav { 
	display: flex;
	justify-content: space-between;
}

The result:

You can also play with the code for this menu bar example on CodePen.

Support

Support for inline-block is excellent: all browsers respect the CSS value, including IE8+.

Conclusion

inline-block is a very, very useful tool to have in your web development arsenal: if you understand the purposes and limitations of inline and block, you can deploy the hybrid value where it is needed in your designs.

Photograph by Daniel Go, licensed under Creative Commons.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.