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 flex
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 flexbox layout 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.