What Is the font-display CSS Property? Complete Guide (2026)
What Is font-display?
font-display is a CSS descriptor inside @font-face that controls how a custom web font behaves while it is loading. It chooses between hiding the text (FOIT — flash of invisible text) and showing fallback text (FOUT — flash of unstyled text). The recommended value for body copy is swap, which shows fallback text immediately and swaps in the custom font when it finishes downloading. The "Ensure text remains visible during webfont load" audit fails when this descriptor is missing.
Key Facts (TL;DR)
font-displayhas five values:auto,block,swap,fallback,optional(CSS Fonts Module Level 4).- Default
autobehaves likeblockin Chrome and Firefox: invisible text for up to 3 seconds. font-display: swapis what most automated audits recommend for the font-display check.- Font swaps cause CLS when fallback and web font metrics differ — fix with
size-adjust,ascent-override,descent-override,line-gap-override(CSS Fonts L4, baseline 2023+). - Google Fonts adds
&display=swapto its URL parameter to apply this descriptor. optionalis the safest value for users on slow connections — it never causes a swap mid-read.
font-display Values: Reference Table
| Value | Block period | Swap period | Behavior | When to use |
|---|---|---|---|---|
auto | Browser default (~3s) | Infinite | Usually equivalent to block | Avoid; be explicit |
block | ~3s invisible | Infinite | FOIT then swap | Icon fonts only (where fallback glyph is meaningless) |
swap | 0ms | Infinite | Fallback shown immediately, swap when ready (FOUT) | Body copy, headings — most websites |
fallback | ~100ms invisible | ~3s | Brief block, short swap window, then keep fallback | Brand-led sites that tolerate small FOIT |
optional | ~100ms invisible | 0ms | Use custom font only if cached or near-instant | Slow connections, performance-critical pages |
How to Add font-display: Step by Step
- Locate every
@font-facerule in your CSS or the Google Fonts<link>. - Add
font-display: swap;to each@font-face, or&display=swapto the Google Fonts URL. - Pick a fallback stack with similar metrics (for example
system-ui,Arial,Georgia). - Use
size-adjust,ascent-override,descent-override, andline-gap-overrideto size-match the fallback to the web font. - Preload the critical web font with
<link rel="preload" as="font" type="font/woff2" crossorigin>. - Re-run an automated audit and confirm the "Ensure text remains visible" check passes.
Self-hosted font with size-matched fallback
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
/* Size-matched fallback eliminates the CLS caused by the swap */
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: 'Inter', 'Inter Fallback', sans-serif;
}Google Fonts URL with display parameter
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossorigin
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"
/>Common Mistakes
- Forgetting fallback fonts in the
font-familystack — the browser still hides text if there is nothing to fall back to. - Using
font-display: blockfor body copy, which recreates FOIT. - Mixing
swapon the regular weight andautoon the bold weight, causing inconsistent loading behavior. - Not preloading the LCP font, which delays the swap by hundreds of milliseconds.
- Using
swapwithoutsize-adjustoverrides — the font swap causes a layout shift and hurts CLS. - Loading every weight and style when the page only uses one or two.
How to Test font-display
- Open Chrome DevTools, throttle to "Slow 4G", and reload — text should never disappear.
- Run an automated audit and check "Ensure text remains visible during webfont load".
- In the Network panel, block the font URL and confirm the page is still readable with the fallback.
- Measure CLS with the
web-vitalslibrary or the Performance panel — the font swap should contribute zero shift if overrides are tuned. - Use Font Style Matcher to dial in
size-adjustvalues.
See our Cumulative Layout Shift guide for the full CLS picture.
FAQ
What is the recommended font-display value?
swap is the right default for body copy and headings. It guarantees text is visible immediately and the audit passes.
Does font-display: swap cause CLS?
Yes, unless the fallback font has matching metrics. Use size-adjust, ascent-override, descent-override, and line-gap-override on a local fallback @font-face to neutralize the shift.
What is the difference between fallback and optional?
fallback still tries to swap in the custom font for about 3 seconds. optional only swaps if the font is already cached or arrives within roughly 100ms — otherwise the user keeps the fallback for the entire page visit.
Should I preload web fonts?
Preload the one or two fonts that paint above the fold. Preloading every font wastes bandwidth and can delay other critical resources.
Does font-display work with Google Fonts?
Yes. Append &display=swap (or any other value) to the stylesheet URL. Google Fonts injects font-display into the @font-face rules it serves.
Why is auto sometimes worse than swap?
auto defers to the browser, which in Chrome and Firefox uses a 3-second invisible block period. That is the FOIT problem swap exists to solve.
Can I use font-display on icon fonts?
Use block for icon fonts — a fallback glyph is usually meaningless, so it is better to wait briefly than to flash the wrong character.
Does this affect AI search engines like ChatGPT and Perplexity?
Indirectly, yes. Slow font loading inflates LCP — a Core Web Vital — and pages with weaker Core Web Vitals tend to rank lower. AI search engines preferentially cite well-ranked pages, so a missing font-display can quietly lower the odds that ChatGPT, Perplexity, or Google AI Overviews pick your page when answering a query.
Conclusion
Use font-display: swap for body copy, pair it with a size-matched fallback using size-adjust and ascent-override to eliminate CLS, and preload the LCP font. This combination passes the font-display audit, keeps text visible on every connection, and avoids the layout shift that historically came with FOUT. Run a Greadme deep scan to find fonts loading without font-display across your site.
