Learn how to use custom fonts on the web with @font-face, Google Fonts, font-display strategies, and proper fallback stacks.
By default, browsers can only display fonts installed on the user's operating system. These are called system fonts or web-safe fonts — families like Arial, Times New Roman, Georgia, and Courier New that are available on virtually every device.
To use custom typefaces, you need web fonts — font files that the browser downloads alongside your CSS. There are two main approaches:
.woff2, .woff) and serve them from your own server using the @font-face rule.The @font-face rule tells the browser: "Here is a custom font family name, and here is where to find the file."
/* Self-hosted font */
@font-face {
font-family: "MyCustomFont";
src: url("/fonts/my-font.woff2") format("woff2"),
url("/fonts/my-font.woff") format("woff");
font-weight: 400;
font-style: normal;
font-display: swap;
}
/* Using the custom font with fallbacks */
body {
font-family: "MyCustomFont", Arial, Helvetica, sans-serif;
}
/* Google Fonts approach (in HTML <head>): */
/* <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet"> */
/* Then in CSS: */
h1 {
font-family: "Inter", sans-serif;
}Loading custom fonts introduces a performance concern: what does the browser show while the font file is downloading?
The font-display property in @font-face controls this behavior:
| Value | Behavior |
|---|---|
auto | Browser default (usually similar to block) |
block | Hide text for up to 3 seconds while loading, then swap |
swap | Show fallback font immediately, swap to custom font when loaded |
fallback | Very short block period (~100ms), then fallback. If the font loads within ~3s it swaps; otherwise the fallback stays |
optional | Very short block period. Browser may decide not to use the custom font at all on slow connections |
Best practice: Use font-display: swap for body text so users can read content immediately. Use font-display: optional for non-critical decorative fonts.
Always provide a fallback stack — a list of fonts the browser tries in order:
font-family: "Custom Font", system-ui, -apple-system, sans-serif;Choose fallbacks with similar metrics (x-height, character width) to minimize layout shift when the custom font loads.
What does `font-display: swap` do?