The Inline-Block Conundrum – Part 2Karen Menezes on August 30, 2013
In Part 1 of the Inline Block article, I had spoken about the key differences between block and inline-level elements, with a demo of how width, height, padding, borders, margins and whitespace behave for inline, inline-block and block displays.
This articles covers three use cases where inline-block layouting is an appropriate solution.
Before we start, here's a bit of trivia:
1. Margins of inline-block boxes do not collapse. See here for more.
2. By default, in ALL browsers, an unknown element in your markup will be treated as an inline element. You may have noticed that in Eric Meyer’s reset.css and Nicolas Gallagher’s normalize.css, a bunch of HTML5 elements are given display: block (or inline-block) to support older browsers.
Back to the point, below are three examples with demos for inline block displays.
CASE 1: You have an h1 heading in your content for semantic reasons. You need to give it a bottom border and background that spans only the width of its content.
Issue: You don’t want to specify the width of the element, since the length of the text could change and that would be a bad idea, in any case.
The solution? Give it a display of inline-block. If you wish to center it, give its parent text-align: center.
Demo here. You can see the border given to the top heading.
CASE 2: You’ve made a responsive grid of four columns with images of different heights within it. You’re using floats, but need to clear every fifth image to avoid the grid from breaking. On narrower screens, you also want to make the grid a two column layout. You will then need to clear every third image on that particular media query. While you could do this using the nth-of-type selector, you want a simpler solution.
Solution (with caveat): inline-block
Inline-block’s Achilles heel is the whitespace generated between such elements. This can very easily cause layout to break, if you don’t account for it. There are a few hacks to overcome this issue. Read this nice article from CSS Tricks.
I generally use an unordered list and omit the end tag on the li elements. This is valid HTML5 markup. The spec says “An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element.” Reference here.
I have no issues leaving my li elements unclosed. For those who do, there is an alternative. It’s important to look at the alternative, because if you’re structuring your layout with divs, the HTML5 spec demands that you use a closing tag.
Therefore, the cleanest way to write it is like this, which is fairly readable and eliminates the whitespace. If you ask me, this is cleaner than any CSS hack that comes along. Just add the closing tag right next to the next opening tag, of the elements that inline-block is being applied to.
Do note that this demo requires box-sizing: border-box universally, as well as max-width: 100% and height: auto on all the images, to work flawlessly.
Note: When flex-box is widely supported for layout, that’s what we should be using.
CASE 3: I have a nice menu that may have more items dynamically added to it from the CMS. I’ve floated them in a container and wish to horizontally centre them. It’s getting a bit tricky with floats. I’m looking for alternatives.
If you’re using an unordered list as your menu container, all you need to do is set display: inline-block to the list items, make sure there’s no whitespace between them and set text-align: centre to the parent, in this case, the ul element. You may want to change the default vertical-alignment (from baseline), probably to top.