Typography is most of web design: four settings that make a site look deliberate
Before colours, before layout, before a single image: the type. Four settings separate a page that looks made from one that looks generated, and an assistant applies all four when asked.
On this page
TL;DR
Ask for four things: a fluid type scale built on one ratio, a line length of 55 to 70 characters, negative tracking and tight leading on large titles, and at most two typefaces served from your own site. Add a floor: 16px body text, AA contrast, real heading levels. None of it needs a designer. All of it needs to be asked for, because an assistant defaults to the browser's settings.
Why type carries the page
A website is mostly text. Whatever the layout does, a visitor reads the headline, then a line under it, then decides. If the type is right, an almost empty page looks intended. If it is wrong, no photograph rescues it.
It is also the quietest tell of a generated page. Not the centered hero, not the three cards: a large title set at the browser's default letter-spacing, and paragraphs running the full width of the screen. Both are what a model produces when nobody asked, and both take one message to fix. The other tells are here; this article is the one that matters most.
Setting one: a scale, not sizes
A page with sizes picked one by one, 14 here, 18 there, 32 for the title, never quite settles. A scale fixes that: one base size, one ratio, and every size on the page is a step on it. Ask for a ratio between 1.2 and 1.25 and six or seven steps, and for the scale to be fluid, so each step grows a little between a phone and a desktop instead of jumping at one breakpoint.
| Step | What it sets |
|---|---|
| Step -1 | Captions, labels, the small print |
| Step 0 | Body text, 16px at least on a phone |
| Steps 1 to 2 | Leads, card titles, the FAQ questions |
| Steps 3 to 4 | Section headings |
| Steps 5 to 6 | The page title, the one line in the hero |
An assistant knows how to write this with clamp() in CSS. What it will not do is decide to. The scale is the first thing to ask for, before any section exists, because everything after it inherits it.
Setting two: the measure
The measure is the length of a line of text. Between 55 and 70 characters, the eye finds the start of the next line without effort. Past 90, it loses its place, and a paragraph that runs across a wide screen is the second most common thing wrong with a generated page.
The fix is one rule: cap paragraphs, leads and list items at about 65 characters, whatever the width of the section around them. A hero can be wide. Its text cannot.
Setting three: tracking and leading on titles
Typefaces are drawn to read at body size. Enlarged to a title, their letters drift apart and their lines float. Large display text wants negative letter-spacing, around minus two to minus four hundredths of an em, and a line-height close to 1. Body text wants the opposite: normal tracking and a line-height of 1.5 to 1.6.
This one setting is most of the difference between a title that looks typeset and a title that looks typed. It costs two lines of CSS, and no assistant adds them unprompted.
Setting four: two typefaces, served by the site
Two typefaces at most: one for display, one for body, or a single family with a bold and a regular. A monospace as a third texture is fine when the subject is technical. Beyond that a page reads as a sampler.
Where they come from matters as much as which. A font pulled from a third-party service at load time blocks the first render on every visit, and it makes your visitors' presence known to that service. Ask for the two files self-hosted as woff2, in the weights actually used and no others, with font-display set to swap so the text shows in a fallback face while the real one arrives. Same rule as the images: the first screen waits for nothing.
| The default | What to ask for |
|---|---|
| Sizes in pixels, picked by hand | One ratio, six steps, fluid with clamp() |
| Paragraphs as wide as the screen | A measure of about 65 characters |
| Titles at default tracking and leading | Minus 0.03em, line-height near 1 |
| Four families from a font service | Two, self-hosted as woff2, swap |
The floor
Under the four settings, a floor nothing goes below. It is not taste, it is whether some visitors can read the page at all.
- Body text at 16px or more on a phone, and nothing under 14px anywhere
- AA contrast: 4.5 to 1 between text and its background, grey on grey included
- One h1, then h2 and h3 in order, so a screen reader and a search engine see the same structure you do
- Text that stays text: never a title baked into an image
- A page that still works zoomed to 200 percent, which is how a lot of people read
The floor is also the last axis of the review grid: under 3 on it, the page does not publish yet.
Say this
Set the typography before anything else: a fluid type scale on one ratio between 1.2 and 1.25, body text at 16px minimum, paragraphs and lists capped at about 65 characters per line, large titles with negative letter-spacing and a line-height near 1, two typefaces at most, self-hosted as woff2 in the weights used with font-display swap, and AA contrast everywhere. Then show me the scale you chose before you build the sections.
Frequently asked
How many fonts should a website use?
Two at most: one for display and one for body, or a single family in two weights. A monospace can be a third texture on a technical subject. Serve them from your own site as woff2, in the weights actually used.
What is the best line length for reading on the web?
Between 55 and 70 characters per line. Cap paragraphs, leads and list items at about 65 characters whatever the width of the section, so the eye finds the next line without effort.
Why do titles on AI-generated sites look off?
They are set at the browser's default letter-spacing and line-height, which are drawn for body size. Large display text needs negative tracking, around minus 0.03em, and a line-height close to 1. Two lines of CSS that no assistant adds unprompted.
Should I load fonts from Google Fonts?
Better not at load time: a third-party font blocks the first render on every visit and tells that service who visited you. Download the two files, self-host them as woff2 with font-display set to swap, and the first screen waits for nothing.