✦ A decade of Canvas craft, now driven by AI — describe it, watch it build live.Start building
Glossary

What Is Font-display: swap?

Font-display: swap is a CSS @font-face descriptor defined in the CSS Fonts Level 4 specification that instructs the browser to immediately render text using a fallback system font while the custom web font downloads, then swap in the custom font once it's available. It eliminates the Flash of Invisible Text (FOIT) by guaranteeing text is always visible during the font load lifecycle. Unlike the default browser behavior, which may hide text for up to 3 seconds, swap has a zero-duration block period and an infinite swap period.

What Is Font-display: swap?

Font-display: swap is a CSS @font-face descriptor defined in the CSS Fonts Level 4 specification that instructs the browser to immediately render text using a fallback system font while the custom web font downloads, then swap in the custom font once it's available. It eliminates the Flash of Invisible Text (FOIT) by guaranteeing text is always visible during the font load lifecycle. Unlike the default browser behavior, which may hide text for up to 3 seconds, swap has a zero-duration block period and an infinite swap period.

How Font-display: swap Works

The CSS Font Loading specification defines a font display timeline with three distinct phases: the block period, the swap period, and the failure period. Font-display: swap sets the block period to 0ms (or an extremely short near-zero window) and the swap period to infinity. This means the browser will never hide text waiting for a font — it renders immediately with the best available fallback, and will replace that fallback with the custom font at any point in the future once the download completes, even if that's several seconds later. During the block period of other values like 'auto' or 'block', browsers typically wait up to 3 seconds before showing fallback text — this produces the Flash of Invisible Text (FOIT), where users see blank space where headlines and body copy should appear. With swap, the browser skips this waiting entirely. The font is flagged as optional-but-desirable: render now with what's available, upgrade later. The actual swap is triggered by the Font Loading API's FontFaceSet, which fires when the downloaded font transitions to 'loaded' status. The visible consequence of the swap period is the Flash of Unstyled Text (FOUT): users briefly see the fallback font before the custom font replaces it, causing a layout shift if the two fonts have different metrics — different x-height, cap height, letter-spacing, or line-height values. This layout shift is measured by the browser's Cumulative Layout Shift (CLS) algorithm, which is a Core Web Vitals metric. A poorly matched fallback font combined with font-display: swap can negatively impact CLS scores even while improving perceived load time. Modern mitigation for FOUT-induced CLS involves the CSS size-adjust, ascent-override, descent-override, and line-gap-override descriptors, also part of CSS Fonts Level 4. These allow developers to adjust fallback font metrics to closely match the custom font's dimensions, minimizing the visual jump when the swap occurs. Google Fonts has begun embedding these override descriptors automatically in its generated @font-face CSS for this reason.

Best Practices for Font-display: swap

Always pair font-display: swap with a carefully chosen system font fallback — for example, if loading Inter, specify 'Helvetica Neue', Arial, sans-serif in your font-family stack so the fallback is visually similar in weight and width. Use the CSS size-adjust descriptor on your fallback @font-face declaration to minimize CLS: tools like the Fallback Font Generator or Fontaine can compute the correct percentage value automatically. Preload your primary custom font using <link rel='preload' as='font' crossorigin> in the <head> — this shifts font fetching to the highest priority queue and dramatically reduces the visible FOUT window without removing its protection against FOIT. Limit font-display: swap to fonts that are critical to layout; for decorative or icon fonts loaded asynchronously, font-display: optional or font-display: fallback may be more appropriate because they won't trigger a late swap that shifts content. Self-host your fonts rather than relying solely on third-party CDN delivery — self-hosting eliminates the DNS lookup and TCP handshake overhead to an third-party origin, giving you predictable load timing and full control over caching headers.

Font-display: swap & Canvas Builder

Canvas Builder outputs production-ready HTML based on the Canvas Bootstrap 5 template, which means its generated @font-face declarations and stylesheet structure are written to support font-display: swap natively — developers aren't starting from an unoptimized base. The clean, semantic HTML output Canvas Builder produces ensures that font preload hints can be placed correctly in the document <head> without fighting a bloated or non-standard DOM structure. For teams using Canvas Builder to rapidly scaffold sites, this means Core Web Vitals-compliant font loading is part of the foundation, not an afterthought to fix before launch.

Try Canvas Builder →

Frequently Asked Questions

Does font-display: swap always improve Core Web Vitals scores?
Not unconditionally — it reliably improves Largest Contentful Paint (LCP) by preventing invisible text from delaying the largest visible content render. However, if your fallback font has significantly different metrics than your custom font, the swap event causes a measurable Cumulative Layout Shift (CLS), which is a separate Core Web Vitals metric. The net effect on your overall score depends on how well your fallback is matched; using CSS override descriptors like size-adjust and ascent-override can neutralize the CLS penalty while keeping the LCP benefit.
What is the difference between font-display: swap and font-display: fallback?
Font-display: fallback has a very short block period (approximately 100ms) and a limited swap period (around 3 seconds). This means text is briefly invisible on fast connections, and if the font hasn't loaded within 3 seconds, the browser locks in the fallback permanently for that page view — it won't swap even if the font finishes downloading afterward. Font-display: swap has no block period and an infinite swap period, meaning it always shows text immediately and always swaps in the custom font whenever it loads, no matter how late. Fallback is preferable when late-arriving font swaps would be more disruptive than a brief FOIT.
How does Canvas Builder handle font-display: swap in its generated HTML output?
Canvas Builder generates clean, production-ready HTML using the Canvas HTML template built on Bootstrap 5, and its output includes properly structured @font-face declarations in the linked stylesheet with font-display: swap already set for custom fonts. Because Canvas Builder outputs semantic, well-formed HTML with <link rel='preload'> tags for critical font assets in the <head>, developers get font loading best practices built in rather than having to retrofit them. This means sites generated by Canvas Builder start with a strong Core Web Vitals baseline for font rendering without requiring manual CSS edits.