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.
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
Related Topics
CLS Layout Shift Causes and Fixes — Cumulative Layout Shift Guide
Core Web Vitals
LCP Optimization Strategies — Largest Contentful Paint Guide
Core Web Vitals
FCP First Contentful Paint Guide — Measuring Initial Render
Supplementary Metrics
Image Optimization for LCP — Formats, Preloading, and Responsive Images
Optimization
Core Web Vitals Scoring Thresholds — Complete Reference
Reference