Inconsistent font metrics are the bane of a front-end developer's attempt to present as uniform as possible an appearance across browsers and platforms. Different fonts can have different metrics that cause unexpected differences in layout and positioning. When matched poorly in CSS font stacks, fallback fonts with metrics sufficiently different from the specified font can cause jumps and realignment as the browser loads the fallback font.
To address all of the above deficiencies in mismatched CSS font stacks I have pinpointed a simple, concise, reliable solution*. It uses repeated declarations of the CSS2 font shorthand property, progressively overriding each other. In contrast to the CSS font stack order of most-preferred to least-preferred, this technique progresses from least-preferred font rule to most-preferred font rule.
A classic CSS font stack is ordered in descending preference, as follows:
font-family: CharisSILW, Georgia, serif;
Let's see the difference in metrics between these three fonts before compensation:
Checking the fallback fonts in the latest project I was working on, I noticed that Times (the font my system picks for serif) is substantially smaller than either Georgia or the desired Charis. To compensate, I've increased the font size to 18px for serif and adjusted the line height proportionately to 1.125em. My shorthand stack technique works as follows:
font: 18px/1.125em serif;
font: 16px/1.25em Georgia;
font: 16px/1.25em CharisSILW;
Note that while Georgia and Charis have similar optical sizes, they have substantially different vertical positions. This technique corrects for both optical size and vertical position by allowing separate combinations of font size and line height per font. After compensation:
Note that while this technique is less elegant than stacks based solely on font-family, it has the advantage of giving added flexibility whilst being almost as concise. Feel free to reach out on Twitter to discuss the #shorthandstack idea, and if you know of prior art, let me know!
font-size-adjust, but the browser support is abysmal. It also doesn't allow changes to line-height or other metrics.