Why Fonts Cause Layout Shift
Fonts cause CLS when they load after the fallback font has already painted. The browser renders the page with a system font, the layout settles into place, then the custom font arrives — and because the custom font has different metrics (letter spacing, line height, character width), every text block reflows. If those blocks are large, the shift is dramatic.
The specific problem on my site: I was loading Google Fonts with a standard link tag in the head. No font-display declaration. No size adjustment. The font loaded 800ms after first paint, and every paragraph snapped to a different size.
The Fix
Font-display: swap plus a size-adjust override on the fallback font. Size-adjust is a newer CSS property that lets you scale the fallback font to approximately match the metrics of the custom font. When the custom font loads and replaces the fallback, the text dimensions are already close — the shift is minimal to invisible.
In Next.js, using next/font/google instead of a manual link tag handles font-display: swap automatically and optimises the loading. For fonts loaded manually, adding size-adjust and ascent-override to the @font-face fallback declaration brought my CLS from 0.31 to 0.04.
Key takeaways
- Add font-display: swap to every custom font to prevent invisible text during load — swap shows fallback text immediately instead of hiding it
- Use next/font/google in Next.js projects — it handles font-display, preloading, and self-hosting automatically, eliminating the most common font-related CLS causes
- For manual font loading, add size-adjust and ascent-override CSS properties to your fallback font declaration to minimise layout shift when the custom font swaps in
Conclusion
Font loading is one of the most overlooked sources of CLS. The fix is a two-line CSS change that takes ten minutes to implement and can move your CLS score from 'poor' to 'good.' No reason not to do it.
Enjoyed this article?

Vivek Kumar Singh
Technical Expert · Full Stack Cloud Engineer · Tokyo, Japan