Type something to search...
How Many Fonts Should a Website Use?

How Many Fonts Should a Website Use?

Open the network panel on a typical marketing site and filter by font. It's common to find a dozen files: a display face for the hero, a sans-serif for the body, a serif for pull quotes, a monospace for one code snippet on the pricing page, plus italic and bold variants of most of them. Nobody planned it that way. Each choice made sense on its own, and the total crept up one font at a time.

The question "how many fonts should a website use?" usually gets a quick answer: two, maybe three. That rule of thumb is reasonable, but it skips the part that matters. What counts as "a font"? What does each one cost? And when is it worth breaking the rule? This post gives you a way to make that decision deliberately, for both the design and the performance side.

Typefaces, Families, and Files

Part of the confusion comes from the word font itself. In everyday use it can mean three different things:

  • A typeface or family, such as Inter or Source Serif. This is what designers usually mean by "two fonts."
  • A style within a family, such as Inter Semibold Italic.
  • A font file, the actual .woff2 the browser downloads.

The distinction between typeface and font gets its own post in Typeface vs Font: What's the Difference?. For this discussion, the useful split is this: the design question is about families, and the performance question is about files. A site with one family can still ship eight files. A site with two families can ship two files if both are variable fonts.

So when you audit a site, count both numbers:

What you countWhy it mattersTypical healthy range
FamiliesVisual consistency, brand clarity, pairing effort1 to 3
Styles per familyHierarchy options, risk of inconsistent use2 to 5
Files downloadedRequests, bytes, render-blocking, layout shift1 to 4
Total font weightLoad time on slow connectionsUnder about 100–150 KB

Those ranges aren't standards, just a sensible starting point. A content-heavy publication with a strong editorial identity can justify more. A dashboard can often get away with zero web fonts by using the system stack.

The Case for One Family

A single well-built family can carry an entire site. Many product sites use nothing but Inter, IBM Plex Sans, or a system UI stack, and they look clean and consistent.

One family works well when:

  • The family is large. It has a range of weights, real italics, and ideally tabular figures and small caps. A family with only Regular and Bold won't give you enough hierarchy.
  • The content is functional. Apps, dashboards, documentation, and settings pages are mostly about scanning and doing, not about voice.
  • You want fewer decisions. Every element uses the same family, so the only choices are size, weight, and color.

You build hierarchy inside one family by varying size, weight, case, letter-spacing, and color. That's covered in depth in Creating Visual Hierarchy with Size, Weight, and Color. Here's what a single-family setup can look like in practice:

:root {
  --font-sans: "Inter", system-ui, sans-serif;
}

body {
  font-family: var(--font-sans);
  font-weight: 400;
  line-height: 1.6;
}

h1,
h2,
h3 {
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.eyebrow {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

code,
pre {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

Notice the code font. It isn't a downloaded web font at all; it's a monospace system stack. That's a useful trick: a family you don't download doesn't cost anything, so system fonts for secondary roles are almost free.

If you want a larger palette while staying inside one design, look at superfamilies: families that include sans, serif, and sometimes mono and slab versions drawn to work together, such as IBM Plex or Source. Superfamilies: Building a Whole Design System from One Type Family covers that approach.

The Case for Two Families

Two families is the most common answer for a reason. It gives you a clear contrast between two roles, usually display (headings) and text (body), without adding much complexity.

Typical pairings:

  • Serif headings, sans body. Editorial feel with comfortable UI text.
  • Sans headings, serif body. Common on long-form reading sites, where the serif carries the prose.
  • Distinctive display face, neutral body face. The display face carries brand personality where it's large and brief, and the body face stays out of the way.

The second family should earn its place by doing something the first can't. If your two families are both neutral grotesque sans-serifs, you've paid for a second download and gained almost nothing visually. Pairing well is a skill of its own; How to Pair Fonts: Rules for Combining Typefaces That Work walks through it.

:root {
  --font-display: "Fraunces", Georgia, serif;
  --font-text: "Inter", system-ui, sans-serif;
}

body {
  font-family: var(--font-text);
}

h1,
h2,
.pull-quote {
  font-family: var(--font-display);
}

When Three or More Is Justified

Three families can work, but each one needs a specific, limited job. Common legitimate third roles:

  • Monospace for code. Developer docs and technical blogs genuinely need it, and readers expect it.
  • A brand display face used only in the logo lockup or hero. Some brands have a custom face that only appears at very large sizes.
  • A script or language-specific face. Multilingual sites often need a family for Arabic, Devanagari, or CJK text that the Latin family doesn't cover.

The language case is different from the others. It isn't adding variety; it's filling a gap. Those fonts usually load only on pages that need them, especially if you split them with unicode-range.

Past three, you should be able to explain each family's job in one sentence. If two families share a job, one of them should go.

Tip

A quick test: list every family on the site and write its role next to it in five words or fewer. If two lines say roughly the same thing, or you can't write a line at all, that family is a candidate for removal.

What Each Extra Font Costs

Design arguments are only half of it. Every font file you add has costs that users feel.

Bytes and Requests

A single Latin-subset WOFF2 for one weight of a typical text face is often in the 15–40 KB range. A full, unsubsetted file can be several times larger. Multiply by every weight and style you load and the total grows fast. Font files are usually discovered late, after the HTML and CSS, so they're often on the critical path for your first readable paint.

Render Timing and Layout Shift

Every web font is another thing that can arrive late and swap in, which can move text around. More fonts means more swaps, and each swap can contribute to Cumulative Layout Shift. The font-display guide covers how to control that behavior.

Consistency Over Time

The cost that doesn't show up in Lighthouse is maintenance. When a site has five families and eleven styles, people use them inconsistently. One page uses the serif for captions, another uses the sans. Eventually every new component prompts the question "which font is this supposed to be?" Fewer options make the right choice obvious.

Counting Styles, Not Just Families

Most bloat comes from styles, not families. A two-family site that loads Light, Regular, Medium, Semibold, Bold, and Black, each with an italic, is shipping twelve files for one family alone.

Before cutting a family, audit the weights:

  1. Search your CSS for every font-weight value in use.
  2. Check whether adjacent weights are visually distinguishable at the sizes you use them. Medium and Semibold often aren't, in body sizes.
  3. Collapse to the smallest set that still gives you hierarchy. Regular, Semibold, and Bold covers most needs. Many sites need only Regular and Bold.

A quick way to see what's actually requested is the browser itself:

// Paste into the console after the page has loaded
const loaded = [...document.fonts].filter((f) => f.status === "loaded");

console.table(
  loaded.map((f) => ({
    family: f.family,
    weight: f.weight,
    style: f.style,
  })),
);

document.fonts lists every @font-face the page declared, and filtering by status shows which ones were actually used and downloaded. The Network panel filtered to "Font" shows the file sizes.

Variable Fonts Change the Math

A variable font puts a whole range of weights (and sometimes widths or optical sizes) in one file. If you need three or more weights of a family, one variable file is usually fewer bytes than the equivalent static files, and it's always fewer requests.

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

With variable fonts, "how many fonts?" becomes almost purely a design question again, because adding a weight costs nothing extra. See Variable Fonts in CSS: One File, Endless Styles for the details. The flip side: if you only use one or two weights, static files can still be smaller.

Zero Web Fonts Is a Valid Answer

The fastest web font is the one you don't load. A system font stack uses whatever UI font the operating system ships: San Francisco on Apple devices, Segoe UI on Windows, Roboto on Android. Text renders immediately with no swap and no layout shift.

System fonts are a strong fit for:

  • Admin panels, internal tools, and dashboards
  • Documentation where speed and familiarity beat personality
  • Body text on a site whose headings use a custom face

The trade-off is that your site looks slightly different on every platform and has less distinct personality. Building a Reliable System Font Stack explains how to write one that holds up.

A Practical Decision Process

When you're setting up typography for a new site, work through these in order:

  1. Start with one family and see whether size, weight, and color give you enough hierarchy. Often they do.
  2. Add a second family only for a distinct role, usually display versus text, and make sure it contrasts clearly with the first.
  3. Use system fonts for minor roles like code, form inputs in admin areas, or fine print, unless they truly need to match the brand.
  4. Pick weights deliberately. Two or three per family is normal.
  5. Prefer variable fonts when you need three or more weights.
  6. Measure the result. Check total font bytes, the number of files, and whether swaps shift the layout.

Here's a summary of common setups:

SetupFamiliesTypical filesGood for
System stack only00Apps, dashboards, internal tools
One variable family11–2Product sites, SaaS, docs
Display + text22–4Marketing sites, blogs
Display + text + mono33–5Developer-focused content
Multi-script2–4VariesMultilingual sites

Common Mistakes

  • Counting families but not files. Two families with six static weights each is twelve downloads.
  • Adding a family for a single element. One decorative heading on the About page rarely justifies a sitewide font load. If you must, load it only on that page.
  • Pairing two near-identical faces. Two similar sans-serifs look like a mistake, not a choice.
  • Loading every weight the font service offers. Embed snippets often default to more styles than you use.
  • Using a web font for code. A good monospace system stack is usually fine and costs nothing.
  • Forgetting italics. If body text uses em, you need a real italic style loaded, or the browser will synthesize a slanted version.

Conclusion

There's no magic number, but there is a sensible default: one or two families, a small set of weights, and system fonts for anything secondary. Each additional family needs a clear role that the existing fonts can't fill, and each additional file needs to justify its bytes and the layout shift it might cause.

When you're unsure, start with less. It's easy to add a display face once you see the design needs more personality, and much harder to remove one after it's spread across a hundred components. Audit the families, count the files, and make every font earn its place.

Share :

Related Posts

A Short History of Typography: From Gutenberg to Variable Fonts

A Short History of Typography: From Gutenberg to Variable Fonts

When you write font-weight: 600 or font-style: italic, you're using vocabulary that is hundreds of years old. "Italic" comes from Renaissance Ita

Continue Reading
Accessible Typography: Font Size, Contrast, and Spacing Guidelines

Accessible Typography: Font Size, Contrast, and Spacing Guidelines

Most accessibility work on a website involves text. Navigation labels, form instructions, error messages, article bodies, button captions: if people

Continue Reading
Bauhaus Typography and Its Influence on Modern Design

Bauhaus Typography and Its Influence on Modern Design

Bold sans-serif type, thick black bars, red accents, text running at an angle, and lowercase-only headlines. If a poster or website uses that combina

Continue Reading