Fonts & Loading

Web Fonts Without Layout Shifts

Fonts & Loading

`@font-face` loads custom fonts. Self-host for speed; use `font-display: swap` to avoid invisible text.

4 min read Level 2/5 #css#fonts#font-face
What you'll learn
  • Load a font with `@font-face`
  • Pick `font-display` wisely
  • Preload critical fonts

To use a font that isn’t on the user’s system, load it with @font-face.

The Pattern

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-var.woff2") format("woff2-variations");
  font-weight: 100 900;       /* a variable font covers the whole range */
  font-style: normal;
  font-display: swap;
}

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

Reference the family by the name you gave it in font-family.

font-display — Critical For UX

ValueBehavior
autoBrowser default — usually like block
blockInvisible text for up to 3s while loading (FOIT)
swapShow fallback immediately, swap to web font when ready (FOUT)
fallbackBrief block, then swap, then never swap
optionalBrief block; if not ready, use fallback forever

swap is the safe default for most pages — users see content immediately, with a brief font switch when the web font arrives.

Variable Fonts

A variable font is one file with every weight (and sometimes style, slant, optical size). Big perf win over loading separate files per weight.

@font-face {
  font-family: "Inter";
  src: url("/inter.var.woff2") format("woff2-variations");
  font-weight: 100 900;   /* declared range */
  font-display: swap;
}

Preload The Important Font

<link
  rel="preload"
  href="/fonts/inter-var.woff2"
  as="font"
  type="font/woff2"
  crossorigin
/>

Tells the browser to fetch the font immediately, in parallel with HTML parsing. Use only for the first paint’s font — preloading everything is counterproductive.

Self-Host vs Google Fonts

Self-hosting is usually faster:

  • No DNS / TLS handshake to Google
  • You control caching
  • No third-party privacy implications

fonts.bunny.net and Google’s font CDN are fine, but downloading the WOFF2 once and serving it yourself is straightforward and better.

Fallback Sizing

The fallback font might be a different size, causing a layout jump when the web font swaps in. Modern CSS has size adjustment properties on @font-face:

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

Tools like fontpie generate these numbers automatically.

Up Next

Beyond font-size — letter-spacing, decoration, transformation.

Text Effects →