Skip to content
AgileLogics
6 min read

Web Fonts

Prerequisites: Fonts and typography

Web fonts let you use typefaces that aren't installed on the visitor's device.

@font-face

@font-face {
  font-family: "Inter";
  src: url("/fonts/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/fonts/InterVariable-Italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

body {
  font-family: "Inter", system-ui, sans-serif;
}
  • Use WOFF2 — compressed and supported everywhere. You don't need older formats anymore.
  • Several @font-face rules with the same family name describe different weights and styles of one family.
  • Serve fonts from your own site when you can (no extra connection, no privacy concerns), and check the font's license.

font-display

What happens while the font downloads:

Value Behavior
swap Show fallback text immediately, swap when the font arrives
fallback Brief invisible period, short swap window, then keep the fallback
optional Use the font only if it's available almost immediately
block Hide text up to ~3 seconds — avoid for body text

swap is a good default for brand fonts; optional avoids layout shifts entirely.

Reducing layout shift

When the web font replaces the fallback, text can reflow. Match the fallback's metrics with an adjusted local font:

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

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

(The right percentages depend on the fonts; tools such as Capsize and framework font helpers compute them.)

Variable fonts

One file contains a continuous range of weights (and sometimes widths, slant, or optical sizes):

h1 { font-weight: 750; }
.condensed { font-stretch: 80%; }
.custom { font-variation-settings: "opsz" 32; }

Usually smaller than loading four or five static weights.

Loading faster

  • Preload the one or two most important fonts: <link rel="preload" href="/fonts/InterVariable.woff2" as="font" type="font/woff2" crossorigin> (see the HTML course).
  • Subset fonts to the characters you need (unicode-range splits a family by script).
  • Use fewer families and weights. System font stacks load instantly.

Icon fonts

Prefer inline SVG icons to icon fonts: they're sharper, accessible with proper labeling, and don't fail as a row of empty boxes when the font doesn't load.