HomeGuidesWeb Design & DevelopmentThe Complete Guide to Web Typography
Web Design & Development

The Complete Guide to Web Typography

Web typography decides whether a website feels considered or thrown together before a visitor reads a single word of the actual copy. Type covers more of a typical page than color, imagery, or layout combined, and it’s usually the last thing anyone thinks about. Get the type system right, the scale, the pairing, the line height, and a site feels calm and easy to read before anyone’s absorbed the message. Get it wrong and even strong copy fights the reader the whole way down the page.

Key takeaways

  • A type system defines size, weight, line height, and letter spacing for every role, not just a font choice.
  • Cap it at two font families, one display and one workhorse, unless there's a documented reason for a third.
  • A modular scale with six to eight sizes builds a hierarchy that actually holds together.
  • clamp() replaces a stack of media-query font-size overrides with one fluid rule.
  • Self-hosted fonts and font-display: swap are performance decisions, not just design ones.

What a type system actually includes

“Pick a nice font” is where most web typography goes wrong, because a font choice alone isn’t a system. A real type system defines size, weight, line height, and letter spacing for every role a page needs: H1, H2, H3, an intro paragraph, body copy, and small captions or labels. Two pages using the same font but different, uncoordinated sizes and spacing will still look inconsistent, because the font was never the whole job.

Treat each decision as a token, not a one-off style on a single page. That’s what lets a developer extend the system to a page type the original design never explicitly covered, using the same logic instead of guessing.

This is also where a type system connects to accessibility. Font size alone doesn’t guarantee legibility if the weight is too light or the letter spacing is too tight for the size it’s set at. A type system worth the name accounts for how each role actually reads on a real screen, not just how it looks in a static design file.

Choosing and pairing fonts

Cap it at two families: one display font for headlines, one workhorse font for body text. A third family needs a specific, documented reason, like a monospace font for a product’s code examples, not just personal preference. Every additional family adds a licensing cost, a page-weight cost, and a consistency risk that outlives whoever added it.

Pair for contrast, not similarity. A serif display paired with a clean sans-serif body, or the reverse, reads as two fonts doing two different jobs. Two similar sans-serifs sitting next to each other usually just looks like a mismatch nobody caught before launch.

Always define a fallback stack, the system fonts a browser falls back to if the licensed or hosted font fails to load, so the brand still holds together in a worst-case scenario.

A few pairings hold up reliably across projects: a warm serif display next to a neutral sans-serif body, or a confident geometric sans display next to a highly legible humanist sans body when the brand wants to stay entirely sans-serif. What matters isn’t copying a specific pairing. It’s making sure the two fonts read as distinct roles at a glance, not as two slightly different versions of the same idea.

Building a type scale that actually scales

A modular scale applies one fixed ratio to a base size, usually 16px for body text, to generate every other size in the system. A ratio around 1.25 produces a balanced, readable hierarchy for most content sites. Tighter ratios, closer to 1.125, suit dense product interfaces where too much size variation gets noisy. Wider ratios, 1.333 and up, suit editorial or marketing pages that want a dramatic jump between a headline and the body underneath it.

Six to eight distinct sizes is the sweet spot. Fewer starves the hierarchy, so headlines and body text start to blur together. More adds inconsistency, since nobody remembers whether a given block of text should be size five or size six.

Worked example at a 1.25 ratio from a 16px base: body sits at 16px, an H3 lands around 20px, an H2 around 25px, and an H1 around 39px, rounded to a clean 40px for the token table. Each step is the previous size multiplied by 1.25, which is what keeps the jumps feeling proportional instead of arbitrary.

Fluid type: one line of CSS instead of five breakpoints

The old way to handle responsive type was a stack of media queries, one font size for mobile, another for tablet, another for desktop, each a separate rule to maintain. The clamp() CSS function replaces all of that with one line: a minimum size, a preferred size that scales with the viewport, and a maximum size. Browser support is effectively universal at this point, so there’s little reason left to hand-write breakpoint overrides for type.

A typical H1 might use a minimum around 1.75rem, scaling up to a maximum around 3rem as the viewport widens. The exact numbers depend on the type scale, but the pattern holds across almost any project.

Line height, line length, and letter spacing

Line height, the vertical space between lines of text, does more for readability than most people expect. Too tight and lines blur into each other. Too loose and the eye loses its place tracking back to the start of the next line. A line height around 1.5 times the font size works well for body copy, tighter for large display text, since big text needs proportionally less breathing room.

Line length matters just as much. Somewhere around 50 to 75 characters per line keeps a paragraph easy to scan. Go much wider and the eye has to work to find the next line. Go much narrower and reading feels choppy, with too many breaks interrupting a sentence’s rhythm.

Letter spacing, or tracking, is one of the few typographic tools that works in reverse depending on size. Small, uppercase labels usually need slightly more letter spacing to stay legible. Large display headlines usually need slightly less, or the letters start to feel disconnected from each other.

Vertical rhythm ties back to the same spacing system that governs margins and padding elsewhere on the page. When a paragraph’s line height and a section’s spacing scale share a common unit, blocks of text and blocks of whitespace line up cleanly down the page instead of feeling like two unrelated systems bolted together.

Web typography and page performance

Type choices are a performance decision as much as a design one. Self-host variable fonts rather than pulling from a third-party font service whenever possible, and set font-display to swap so text renders immediately in a fallback font instead of staying invisible while the custom font loads. A page that hides its own text until a webfont downloads is choosing looks over usability, and it can measurably hurt load-time metrics like Largest Contentful Paint.

Variable fonts specifically are worth the switch for most projects. A single font file can cover the full weight range, from light to bold, instead of loading a separate file for every weight the design uses.

Preload the most important font file, usually the body font, since it renders the most text on the page, with a resource hint in the document head rather than letting the browser discover it late in the CSS. That small change alone can meaningfully improve how fast text becomes visible on a slow connection.

Where web typography usually goes wrong

Too many fonts is the most common mistake, three or four families fighting for attention on one page, usually because nobody set a hard limit early. Poor contrast is the second, light gray text on a white background that looks elegant in a mockup and unreadable on an actual phone screen outdoors. Ignoring mobile is the third: a type scale tuned for a large desktop monitor that turns into a wall of oversized headlines and cramped body text the moment it hits a 375px viewport.

Here’s the blunt version: nobody has ever complimented a website on its font choice. They notice good typography by not noticing it at all, the words are just easy to read. That’s the actual goal. The same discipline that governs a full brand identity system applies just as much to type. If your site’s type needs a rebuild instead of a patch, that’s usually a website design conversation. Get in touch to talk through what’s already there.

One more habit worth building: test the type system with real copy, not lorem ipsum, before it ships. Placeholder text is uniform in a way real writing never is, short words, long words, punctuation, the occasional all-caps acronym, and a scale that looks perfect with filler text can reveal awkward wrapping or cramped line breaks the moment actual sentences replace it.

Ready to build the whole thing right?

One studio, one system, from first mark to full scale.

Start a project

Frequently asked questions

How many fonts should a website use?
Two: one display font for headlines and one workhorse font for body text. A third family needs a specific reason, not just a design preference, since every added font is a loading-performance cost and a consistency risk.
What's the best line height for body text?
Around 1.5 times the font size for most body copy. Large display headlines can run tighter, closer to 1.1 to 1.2, since bigger text needs proportionally less vertical space to stay readable.
What does clamp() do for web typography?
It lets a font size scale fluidly between a minimum and maximum value as the viewport width changes, replacing a stack of separate media-query overrides with a single CSS rule. Browser support is now close to universal.
How wide should a line of text be?
Somewhere around 50 to 75 characters per line for body copy. Much wider and the eye struggles to find the next line. Much narrower and reading feels choppy from too many breaks.
Should I use a free Google Font or a paid, licensed font?
Either can work well. What matters more is self-hosting the font file for performance, defining a solid fallback stack, and staying within a two-family limit. A free font used well beats a premium font used poorly.
Start a project