Text that reads well
Choosing fonts and loading them without slowing the page, sizes and spacing that are comfortable to read, and styling links and lists.
By the end you can
- Set a font that works everywhere, and load a custom one safely
- Choose sizes, line height and line length people can read
- Style text without making it harder to understand
- Style links and lists, including the states that matter
Easier if you did first
step 1 of 4
Choosing a font, and loading it
font-family takes a list, not one name. The browser tries each in turn and uses the first one it has.
Think of asking a shop for a brand of rice. If they do not have it, you want them to hand you something similar rather than nothing at all. The list is you saying what to fall back to.
Always end the list with a general kind: sans-serif, serif or monospace. That is the browser's own guarantee that something sensible appears.
The cheapest choice is the system font stack: system-ui and friends. It uses whatever font the visitor's device already has, so nothing is downloaded and the text appears instantly. On a phone in Kumasi on a slow connection, that is a real gift.
A custom font has to be downloaded, which costs time before anything can be read. Three rules keep that honest. Load only the weights you actually use, because each one is a separate file. Use font-display: swap, which shows the fallback immediately and swaps when the real font arrives, instead of leaving a blank space. And preconnect to the font's server so the connection is open before the request.
Set a sensible font stack for the page on the right, and a different one for the code.
body {
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
code {
font-family: ui-monospace, "Courier New", monospace;
}
@font-face {
font-family: "Brand";
src: url("/fonts/brand.woff2") format("woff2");
font-display: swap; show the fallback at once, swap when ready
}What these words mean
- font-family
- A list of fonts to try, in order.
- fallback
- The next font in the list, used when the one before it is missing.
- system font stack
- Whatever font the device already has. Nothing to download.
- sans-serif / serif / monospace
- General kinds of font. Always end your list with one.
- woff2
- The font file format for the web. Smallest, and supported everywhere.
- font-display: swap
- Show the fallback immediately, swap when the real font loads.
- weight
- How bold a font is, from 100 to 900. Each weight is its own file to download.
Easy to get wrong
font-family: "Brand";
font-family: "Brand", system-ui, sans-serif;
If the font fails to load, and on a bad connection it will, the browser falls back to its default, which is usually Times New Roman. Your careful design turns into a 1996 word processor.
Loading six weights of a font because the design uses them
Two or three, or a variable font
Each weight is its own download before anyone can read a word. Most designs genuinely need a normal and a bold.
What we check
- The page's font list ends with a general kind
- The code has its own font
- That font is monospace
- The page uses the system font