how many fonts should a website have? the two-family answer, done properly
design · Oct 6, 2026 · 5 min read
one, or two. that is the whole answer, and the rest of this post is about doing that correctly, because the interesting failure is not "seven fonts" — it is the two-font pairing chosen badly, or the one font whose weight files quietly cost seconds.
why the ceiling is two
every typeface on the page is a voice. one voice, used across weights and sizes, reads as intentional — like a person who speaks in their own tone everywhere. every additional voice raises the question "why does this sound different?", and visitors feel the inconsistency before they can name it. the multi-font page is the typographic cousin of the too-many-colors page, and it lands on the same list of tells in what makes a website look cheap.
the professionals' page you admire probably uses one family. its richness comes from weights — regular, medium, bold — and from scale: three or four text sizes, used consistently. variety of hierarchy, uniformity of family.
the two-family pattern, if you take the second
the classic split that works: a display font for headings, a workhorse for everything else. the display font carries personality; the workhammer carries paragraphs, forms and buttons. the pairing rules that keep it from going wrong:
-
contrast on one axis. pick a serif display over a sans body, or a geometric display over a humanist body — fonts that differ clearly. two fonts that almost match read as a mistake, not a choice.
-
the workhorse must actually work. headings appear in dozens of sizes; body text carries hundreds of words on a screen. test the body font at small sizes on a phone before committing to it for its personality.
-
the third font needs a job. occasionally a mono for code, a script for one signature element. that is a role with a name and one place to appear — the moment the "special" font appears in three places, it is decoration and should go.
the cost nobody quotes you: font files
here is the part that makes font choice a performance decision, not just an aesthetic one. every font weight you load is a file the visitor's browser must download before text looks right. a family used at four weights is four files; two families at three weights each is six. and text is visible on first paint, so font files sit directly on the loading path that core web vitals measures — the slow font shows up as invisible text swapping in late, which visitors experience as jank.
the rules that keep it fast: two weights are usually enough (regular, bold); load only the characters you need (subsetting); and prefer modern formats. one of the quietest speed wins on most sites is simply deleting the three weights nobody can distinguish anyway.
how to choose without a designer
-
stay with the system font. genuinely underrated: the native font of the visitor's device loads instantly, reads perfectly, and costs zero. this site uses a custom display face but system stacks for a lot of the work — the mix is deliberate.
-
if you go custom, pick a family with many weights and use them instead of a second family. one variable font can hold every weight in a single file, which is the best of both.
-
steal the pairing, not the site. when you see a site whose type you admire, inspect it: fonts used, how many weights, which font does headings. mimicry of structure is how taste is trained.
FAQ: the questions i actually get
are the default template fonts bad?
they are safe and overused — which is a real complaint, since looking like every other site is its own problem. but changing the heading font alone, keeping the body, transforms the feel for an hour's work.
can i use my logo's font on the website?
often, badly: logo fonts are display designs with tiny character sets. if it has a full alphabet at readable weights, use it for headings only. never for body text.
do i have to pay for fonts?
many excellent families are free (google fonts licenses everything for web use). paid fonts buy distinctiveness, not quality — pay when the free options all feel taken, not as a default.