Font Loading and CLS — Preventing Layout Shifts from Web Fonts

Prevent Cumulative Layout Shift caused by web font loading. Learn about FOUT, FOIT, font-display strategies, size-adjust, and font preloading techniques.

Optimization

Detailed Explanation

How Web Fonts Cause Layout Shifts

Web fonts are a common source of CLS. When a web font loads and replaces the fallback system font, text reflows because the two fonts have different metrics (character widths, line heights, spacing).

FOUT and FOIT

  • FOUT (Flash of Unstyled Text): Text renders in the fallback font, then swaps to the web font when it loads — causing a visible layout shift
  • FOIT (Flash of Invisible Text): Text is invisible until the web font loads — then suddenly appears, shifting surrounding content

font-display Strategies

@font-face {
  font-family: "Custom Font";
  src: url("/fonts/custom.woff2") format("woff2");

  /* Options: */
  font-display: swap;     /* Show fallback immediately, swap when ready (FOUT) */
  font-display: block;    /* Hide text briefly, swap when ready (FOIT) */
  font-display: optional; /* Show fallback, only swap if font loads very fast */
  font-display: fallback; /* Brief block period, then fallback, swap if fast enough */
}

For CLS optimization, font-display: optional is best because it never causes a visible font swap. The font is used only if it loads during a very short block period (~100ms).

CSS size-adjust and Override Properties

Modern CSS lets you match fallback font metrics to your web font, eliminating layout shift even with font-display: swap:

/* Adjust fallback to match web font metrics */
@font-face {
  font-family: "Adjusted Arial";
  src: local("Arial");
  size-adjust: 105.4%;
  ascent-override: 92%;
  descent-override: 22%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Custom Font";
  src: url("/fonts/custom.woff2") format("woff2");
  font-display: swap;
}

body {
  font-family: "Custom Font", "Adjusted Arial", sans-serif;
}

Tools like Fontaine and Next.js next/font calculate these adjustments automatically.

Preloading Fonts

Preload critical fonts to ensure they arrive early:

<link
  rel="preload"
  href="/fonts/custom.woff2"
  as="font"
  type="font/woff2"
  crossorigin
>

Note: The crossorigin attribute is required for font preloads, even for same-origin fonts.

Self-Hosting vs Google Fonts

Self-hosted fonts load from your domain, avoiding the DNS + connection overhead of a third-party. For Google Fonts, consider downloading and self-hosting the subset you need.

Use Case

Font loading optimization affects every website that uses custom web fonts. Blog and content sites, marketing pages, and brand-focused sites that rely on specific typography are especially impacted. Using next/font in Next.js or Fontaine in other frameworks automates much of this work.

Try It — Web Vitals Reference

Open full tool