How to pair fonts that work
Font pairing is less about finding two beautiful typefaces and more about giving each one a clear job. The heading font sets the tone in a few words at large sizes. The body font has to disappear: it should be comfortable to read for several minutes at 16 to 20 pixels without anyone noticing it. Most good pairings come from one of three approaches.
1. Contrast in classification
The classic move is a serif headline over a sans-serif body, or the reverse. Playfair Display over Source Serif 4 reads as editorial; DM Serif Display over DM Sans is the same idea from a single type family, so the proportions already match. Contrast works because the eye immediately understands which text is which.
2. Shared skeleton
Fonts with similar x-heights and widths sit comfortably together even when their styles differ. Look at the lowercase letters in the preview: if the body text looks noticeably taller or wider than the heading at a similar size, the pair will feel slightly off. Superfamilies like IBM Plex, Instrument and Red Hat are designed to solve this for you.
3. One family, two weights
When in doubt, use one versatile family and let weight do the work: Inter at 800 for headings and 400 for text, or Newsreader at 600 and 400. It is the lowest-risk pairing there is, and it halves the number of font requests.
Tuning what you see
- Type scale controls the jump between sizes. Smaller ratios (1.125 to 1.25) suit dense apps and docs; larger ratios (1.333 and up) make marketing pages feel confident. The preview uses the ratio to the fourth power for the hero headline.
- Line height for body text usually lands between 1.5 and 1.7. Wide columns and fonts with large x-heights need more.
- Letter spacing on headings: tighten big display text slightly (around
-0.02em), and loosen all-caps or very small text instead.
Loading fonts without slowing the page
The generated code requests only the weights you picked, plus a bold for body text, and uses display=swap so text is visible while fonts download. The two preconnect hints let the browser open the connection to Google early. If you need the last bit of speed, self-host the WOFF2 files:
@font-face {
font-family: "Inter";
src: url("/fonts/inter-var.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}
Always include a sensible fallback stack after the web font name. The CSS output adds Georgia, serif for serif families and system-ui, sans-serif for sans families, so the layout shift when the real font arrives stays small. For sizing that scales smoothly between phone and desktop, run your chosen sizes through the fluid type scale generator, and check your text and background colors with the contrast checker.
Frequently asked questions
How many fonts should a website use?
Two is the sweet spot: one for headings and one for body text. A third, usually a monospace for code or a display face for a single hero, is fine if it has a clear job. Every extra family adds download weight.
Can I pair two sans-serif fonts?
Yes, as long as they differ enough to look intentional. Pair a geometric or grotesque display sans with a neutral, open text sans, and lean on weight contrast. Two near-identical sans fonts just look like a mistake.
Is it faster to self-host Google Fonts?
Usually a little, because the browser skips a connection to a second domain and you control caching. Download the WOFF2 files, declare them with @font-face and font-display: swap, and preload the one used above the fold.
Why does the link only include certain weights?
Each weight is a separate download. The generated link asks only for the heading weight, the body weight and a bold for body text, which keeps the font payload small.