vertical-align is hard. Have you ever wanted to vertically center an icon with text? This usually means "vertically align with capital letters", as visually, a text line goes from baseline up to the capital top. That's because text usually starts with a capital letter, plus descenders are far less frequent than ascenders.
In this card we'll vertically center an icon (or any "blockish" inline element, really) with the capital letters of surrounding text. This works well with our modern approach to SVG icons, or e.g. for custom list icons. Note that it won't work with "text" icons that scale with font-size.
Technical background
- All text has a "baseline". It is the bottom edge of most letters, like A or a.
- The browser aligns all inline elements to the baseline of their container (i.e. the baseline of the text of their container).
- Elements containing text have their text baseline aligned (to the baseline of their container)
- Replaced elements (
<svg>,<img>) and emptyinline-blockelements have their bottom edge aligned (to the baseline of their container)
-
vertical-align: middlealigns an element's baseline to the middle of a lowercasex. We cannot use it, since we want to align to uppercase letters.
Solution
We'll move the bottom edge of the icon up to the middle of a capital letter, then push it down by half its own height. This will center the icon vertically to uppercase letters – no matter the icon height or the surrounding font size!
.icon {
display: inline-block;
height: var(--icon-height);
vertical-align: calc(0.5cap - var(--icon-height)/2);
}
Notes:
- Icon and any wrappers must not set
font-family,font-size,vertical-align, since1capis measured in the icon's own font. - The
capunit is Baseline since 2024 Show archive.org snapshot . - Any wrapper elements must be
display: inline. Aninline-blockwrapper creates its own line, so the icon would be centered within the wrapper instead of the text. - If the icon is a replaced element (
svg,img), it may also bedisplay: inline.