font-display is a @font-face descriptor that tells the browser what to do with text styled with a custom font while that font is still downloading. Without it, the browser's default behavior is to hide the text for up to 3 seconds (FOIT, Flash of Invisible Text), then either swap to the fallback font (Chrome / Firefox) or stay invisible (older Safari).
Five values:
auto-- whatever the browser thinks is best. Equivalent toblockin most browsers (i.e., FOIT). The default if you don't specify.block-- block period (text is invisible for up to 3s), then swap to fallback if font hasn't loaded; swap to custom font when it does. Causes visible FOIT.swap-- no block period. Shows fallback text immediately. When the custom font loads, swaps in. Causes FOUT (Flash of Unstyled Text) -- visible re-layout when the swap happens, but text is always readable.fallback-- 100ms invisible block, then fallback. If font loads within 3s after that, swap. Otherwise stick with fallback. Compromise between block and swap.optional-- 100ms invisible block. If font isn't ready, use fallback FOR THE WHOLE PAGE LOAD (no swap). Best for non-critical decorative fonts; effectively zero layout shift.
Decision flow:
- Brand fonts that MUST appear correctly (logo wordmarks, hero headings):
swap-- accept the FOUT, prioritize text being readable. - Body text:
swap-- always. - Decorative / icon fonts where fallback would look wrong:
block-- accept the FOIT. - Lazy-loaded section fonts:
optional-- skip the swap if it can't be loaded fast.
Combine with <link rel="preload" as="font" type="font/woff2" crossorigin> for above-the-fold critical fonts to minimize the FOUT swap window.