What is font-display?

font-display is a CSS descriptor inside @font-face that controls how a browser handles the "font loading period" — the time between when a page starts rendering and when the custom font file is available to display text.

Without a clear strategy, browsers make different choices. Chrome hides text briefly, Safari hides it longer, Firefox shows fallback text — the same page behaves differently on each browser. font-display unifies the behaviour across browsers by making the choice explicit.

The five values explained

font-display: auto

The browser chooses based on its own heuristics. In practice, Chrome and Firefox behave like swap, while Safari behaves closer to block. This is not recommended because behaviour is inconsistent and can change with browser updates.

font-display: block

Text is invisible for up to 3 seconds while the font loads. If the font arrives within that window, the text appears in the custom font. If not, the browser renders the fallback font — and will swap to the custom font when it finally arrives, no matter how long it takes.

The 3-second block period is the worst part. Users see an empty space where the headline should be. On slower connections or with large font files, LCP (Largest Contentful Paint) can exceed 4 seconds, which is a Critical failure in Core Web Vitals.

Only use block for icon fonts — if fallback glyphs would render as broken symbols, an invisible space is less bad than visible breakage.

font-display: swap

Fallback text renders immediately, and the custom font swaps in when it arrives. There is no invisible-text period. The tradeoff is FOUT (Flash of Unstyled Text) — users briefly see a fallback font, then the custom font. For text content, FOUT is universally preferable to FOIT (Flash of Invisible Text).

swap is the correct default for body text, headlines, and any content users need to read immediately.

font-display: fallback

A middle ground. Text is invisible for a very short block period (roughly 100ms), then falls back to the fallback font. The custom font can only swap in within the first 3 seconds of page load. After that window closes, the fallback font remains for that page load.

The 3-second swap window means: users on slow connections or with slow caches will see the fallback font for that page view. The next page load may show the custom font because the font is cached. This reduces layout shift compared to swap but sacrifices the custom font on slow first loads.

font-display: optional

Text is invisible for ~100ms, then falls back. The custom font only swaps in if it is available within that 100ms window — which is almost never on first load. If the font is already cached from a previous visit, it may be available within 100ms and swap in.

The tradeoff is severe: users on slow first visits essentially never see the custom font. Users on repeat visits do. In exchange, there is zero layout shift caused by font swaps, which is excellent for CLS.

Use optional only when layout stability is more important than typography fidelity — rarely the case for editorial sites, sometimes appropriate for dense dashboards.

Timing comparison

ValueInvisible periodFallback visible periodSwap window
autoVaries by browserVariesVaries
block~3 seconds0 secondsUnlimited
swap0 secondsImmediateUnlimited
fallback~100ms~100ms~3 seconds from load
optional~100ms~100msNone after initial paint
The 3-second rule: Every font-display strategy except optional allows the font to swap in at any time. That swap causes CLS (Cumulative Layout Shift) if the fallback font has different metrics than the custom font. See the metric-override section below to eliminate this shift.

Impact on Core Web Vitals

Largest Contentful Paint (LCP)

LCP measures when the largest visible element renders. If your LCP element is a headline in a custom font:

  • block delays LCP until the font arrives — typically 1–4 seconds on first load. Critical failure.
  • swap reports LCP as soon as the fallback text paints — often under 1 second. Pass.
  • fallback delays LCP by ~100ms only. Pass.
  • optional reports LCP as soon as the fallback text paints. Pass.

Cumulative Layout Shift (CLS)

CLS measures unexpected layout movement. If your custom font has different metrics (line heights, character widths) than the fallback font, the text reflows when the font swaps in. This is a layout shift.

  • swap can cause CLS if the swap happens after first paint (common).
  • fallback reduces CLS because most swaps happen within the 100ms window before users perceive them.
  • optional eliminates CLS entirely by not swapping after first paint.
  • block has minimal CLS from fonts but maximum LCP harm.

The best of both worlds is swap combined with metric-adjusted fallbacks (below). This gives instant text paint (good LCP) with negligible layout shift (good CLS).

Metric-adjusted fallbacks

Modern CSS provides four descriptors that adjust a fallback font's metrics to match your primary font. When the font swaps, the text barely shifts because the fallback was already rendering at approximately the same size and position.

@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22.43%;
  line-gap-override: 0%;
}

body {
  font-family: "Inter", "Inter Fallback", sans-serif;
}

The exact values depend on the metrics of both fonts. Chrome DevTools calculates these values automatically in the Network panel: select your font, look at the "Fallback" tab, and copy the suggested CSS. Firefox and Safari show similar data.

This technique reduces CLS from ~0.05 to under 0.01 in most cases — enough to pass Core Web Vitals without sacrificing custom fonts.

Recommendations by content type

Content typefont-displayRationale
Body textswapReading must never be blocked; readability of fallback text is acceptable
Headlines (LCP element)swapFallback renders instantly; metric-override prevents shift
Hero section headlineswap + metric overrideHighest-impact LCP element; swap + adjusted fallback is optimal
UI labels and buttonsswapUsers need to read controls immediately
Icon fontsblockFallback glyphs render as broken symbols; blocking is less bad
Decorative display fontsoptionalCustom font is nice-to-have; fallback is fine
Print-style documentsfallbackBalance reading speed with visual fidelity

Common mistakes

  • Using block for body text — guarantees LCP failure on slow connections.
  • Using auto and assuming it behaves like swap — behaviour varies by browser.
  • Forgetting font-display entirely — defaults to auto, which is unpredictable.
  • Mixing strategies across fonts — a body font with swap and a heading font with block creates inconsistent LCP behaviour.
  • Not including metric overrides — even swap can cause CLS if the fallback metrics are very different.

Generate your @font-face CSS

Use the OmniFonts font-display Generator to build a complete @font-face rule with your chosen strategy, or the @font-face Generator for a full rule with all properties including metric overrides.

Frequently asked questions

What is the best font-display value?

swap for body text and headings. optional when you cannot accept any layout shift. block only for icon fonts.

Does font-display affect Core Web Vitals?

Yes. swap minimizes LCP delay. block can severely harm LCP. optional has the smallest CLS impact but sacrifices custom font display on slow connections.

What is FOIT and FOUT?

FOIT (Flash of Invisible Text) is caused by block. FOUT (Flash of Unstyled Text) is caused by swap. FOUT is universally preferred over FOIT.

Is font-display: auto ever a good choice?

Rarely. auto delegates to browser heuristics which differ across browsers. Explicitly choosing swap is more reliable.

Can I use metric overrides with Google Fonts?

Yes, by adding a @font-face rule that declares the fallback with metric overrides, then including it in your font-family stack after the Google Font. Chrome DevTools calculates the exact values you need.