Typography on the Web: A Practical Guide
Typography is 95% of web design. That's not my opinion - it's an old industry saying, and it's true. Most of what you see on any website is text. Get typography wrong, and nothing else matters.
The good news? You don't need to be a font nerd to make good choices. There are straightforward principles that work every time.
Picking Fonts: Less Is More
Here's the rule: use one font family. Maybe two if you really need it. Never three.
One font for headings, one for body text is a classic combo. But honestly? A single well-chosen font family with multiple weights can do everything you need. It's simpler to maintain and always looks cohesive.
For body text, prioritize readability. That means high x-height (the height of lowercase letters), open letterforms, and clear distinction between similar characters (I, l, 1). Sans-serifs like Inter, IBM Plex Sans, or Source Sans Pro are safe choices. If you want serifs, Georgia, Lora, or Source Serif Pro work great.
For headings, you have more freedom. Display fonts can add personality. But make sure they're still legible. Some display fonts fall apart at smaller sizes.
Where to get fonts: Google Fonts is free and good enough for most projects. If you want something more unique, try fontshare.com, fontsource.org, or paid options like Adobe Fonts.
Setting Up a Type Scale
A type scale is a set of predefined font sizes that work together harmoniously. Don't just pick random pixel values. Use a ratio.
Common ratios:
- 1.2 (Minor third) - Subtle, good for dense interfaces
- 1.25 (Major third) - Balanced, most versatile
- 1.333 (Perfect fourth) - More dramatic hierarchy
- 1.5 (Perfect fifth) - Bold, great for marketing pages
Start with your base size (usually 16px for body text), then multiply up for headings and divide down for small text.
Using 1.25 ratio with 16px base:
- Small: 12.8px (round to 13px)
- Base: 16px
- Large: 20px
- H4: 25px
- H3: 31px
- H2: 39px
- H1: 49px
Tools like typescale.com generate these for you. Pick a ratio, export the CSS, done.
Line Height: The Most Common Mistake
Default line height in browsers is around 1.2. That's too tight for body text. Your paragraphs will look cramped and be harder to read.
Rules of thumb:
- Body text: 1.5 to 1.75 line height
- Headings: 1.1 to 1.3 line height
- Short text (buttons, labels): 1.0 to 1.2 line height
Larger text needs less line height because the letters themselves provide enough vertical spacing. Smaller text needs more breathing room.
Also: line height should be unitless in CSS. Write line-height: 1.5, not line-height: 24px. Unitless values scale properly when font size changes.
Line Length: The Forgotten Dimension
Ever tried reading a paragraph that stretches across your entire monitor? It's exhausting. Your eyes lose their place when jumping to the next line.
Optimal line length is 45-75 characters per line, with 65 being the sweet spot. For most fonts at 16px, that's roughly 600-700px wide.
This is why content sites use narrow columns. It's why max-width on your main content area is essential. Without it, your text becomes unreadable on large screens.
Quick CSS fix:
.prose { max-width: 65ch; }
The ch unit is the width of the "0" character. Using it makes your width adapt to the font you're using.
Font Weight and Emphasis
Most font families offer weights from 100 (thin) to 900 (black). You don't need all of them.
Typical setup:
- 400 (Regular) - Body text
- 500 or 600 (Medium/Semi-bold) - Subheadings, emphasis
- 700 (Bold) - Headings, strong emphasis
That's it. Three weights handle almost everything. Loading more weights means more font files, slower pages.
For emphasis within text, bold is fine. Avoid italics for long passages - they're harder to read. Never use underlines except for links (users expect underlines to be clickable).
Spacing: The Secret Ingredient
Good typography isn't just about the letters. It's about the space around them.
Margin above headings should be larger than margin below. This groups the heading with its content instead of floating between sections. I typically use 2x the margin above that I use below.
Paragraph spacing should be consistent. Either indent first lines with no space between paragraphs (book style) or add space between paragraphs with no indents (web style). Don't mix them.
Letter spacing usually doesn't need adjustment for body text. But for ALL CAPS text, add positive letter spacing (around 0.05em) to improve readability. For large headings, you might reduce letter spacing slightly (-0.01em to -0.02em) to tighten things up.
Responsive Typography
Your 49px heading looks great on desktop. On mobile, it's two words per line.
Options:
Fluid typography scales font size smoothly based on viewport width. Use CSS clamp():
font-size: clamp(2rem, 5vw, 3.5rem);
This sets a minimum (2rem), a preferred size (5vw), and a maximum (3.5rem). The browser picks what fits.
Breakpoint-based changes font size at specific widths. Less smooth but more predictable. Good when you need precise control.
Whichever approach you use, test on real devices. Font rendering varies across operating systems and screens.
Performance: Don't Kill Your Load Time
Custom fonts can destroy performance if you're not careful.
Subset your fonts. If you only use Latin characters, don't load Cyrillic, Greek, and Vietnamese. Most font services offer subsetting options.
Use modern formats. WOFF2 is smaller than WOFF, which is smaller than TTF. Serve WOFF2 with WOFF fallback.
Preload critical fonts. Add <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin> in your head. This tells the browser to fetch fonts early.
Use font-display. font-display: swap shows fallback text immediately, then swaps in your custom font when it loads. Users see content faster.
For most sites, 2-3 font files total (regular, bold, maybe italic) is plenty. Every additional file adds latency.
Common Mistakes to Avoid
Justified text. It creates uneven word spacing and rivers of white space. Left-align everything except maybe pull quotes.
Centered body text. Hard to read for more than a line or two. Center headings if you want, but body text should be left-aligned.
Too many font sizes. If you have 15 different font sizes, your type scale is broken. You should need 6-8 at most.
Skipping the scale on mobile. Mobile headings should be smaller than desktop headings. Don't just let them wrap awkwardly.
Forgetting about line length on mobile. Even on small screens, very short lines (under 30 characters) are choppy to read. Find the balance.
Your Typography Checklist
Before shipping:
- Base font size at least 16px?
- Body line height between 1.5 and 1.75?
- Line length under 75 characters?
- Type scale consistent and intentional?
- Fonts loading fast with proper display strategy?
- Tested on mobile and different browsers?
Typography that disappears into the reading experience is typography that's doing its job. Make it invisible by making it good.