Typography · · 9 min read
Type Scale for Websites: How to Set Font Sizes
How to build a type scale for websites: pick a base size and a ratio like 1.25 or 1.333, set line height and tracking, and make it fluid with clamp().

A type scale is a short list of font sizes, each one a fixed ratio larger than the last, starting from your body size. For most websites, a base of 16px and a ratio between 1.2 and 1.333 gives you every size you need, from captions to the hero headline, with relationships that look intentional instead of guessed. Add line heights that tighten as sizes grow, a little negative tracking on display sizes, and clamp() to make it all fluid, and you have a type system that holds up across a whole site.
Key takeaways
- Start from a body size of 16px (1rem) and multiply by one ratio to get every other size.
- Pick the ratio by content: 1.2 for dense products, 1.25 to 1.333 for marketing pages, 1.5 and above for editorial or expressive sites with few heading levels.
- Line height should fall as size rises: about 1.5 for body text, about 1.1 for big headlines.
- Display sizes usually want slightly negative letter spacing; small uppercase labels want positive.
- Use
clamp()with a rem component so headings scale smoothly between phone and desktop without breaking browser zoom.
Why a type scale beats picking sizes by eye
Most sites that feel slightly off typographically are not using bad fonts. They are using too many sizes: 15px here, 17px there, a 34px heading on one page and a 36px heading on another. Each choice looked fine in isolation, but together they blur the hierarchy and make the site feel assembled rather than designed.
A scale fixes this by limiting the options. Instead of asking "what size should this heading be?", you ask "which step is it?". That question is faster to answer, easier to review, and much easier to hand to a developer. It also makes your sizes predictable as design tokens, which matters once the site grows. (More on that in design tokens explained.)
How a modular scale works
A modular scale has two inputs: a base size and a ratio. You multiply the base by the ratio to go up one step, and divide to go down. With a base of 16px and a ratio of 1.25:
- Step 0: 16px
- Step 1: 16 × 1.25 = 20px
- Step 2: 20 × 1.25 = 25px
- Step 3: 25 × 1.25 = 31.25px
- Step 4: 31.25 × 1.25 = 39.06px
Every heading is now related to the body text by the same proportion. That shared proportion is what makes a well set page feel calm even when the sizes vary a lot.
The common ratios and when to use them
Many of the popular ratios borrow names from musical intervals. The names do not matter much; the spread does.
| Ratio | Name | Six steps above 16px reach | Good for |
|---|---|---|---|
| 1.125 | Major second | about 32px | Dense apps, admin tools, data tables |
| 1.2 | Minor third | about 48px | Product UI, documentation, blogs |
| 1.25 | Major third | about 61px | Most marketing sites and landing pages |
| 1.333 | Perfect fourth | about 90px | Bold marketing pages, portfolios |
| 1.5 | Perfect fifth | about 182px | Editorial layouts with few heading levels |
| 1.618 | Golden ratio | about 287px | Expressive, poster-like pages |
Two things jump out from that table. First, small ratios give you many usable steps close together, which is what a product with five heading levels needs. Second, large ratios run out of room quickly: at 1.618 your third step is already about 68px, so you only get a body size, one subheading, and a giant headline. That can be exactly right for a portfolio with a statement section and very little else, and exactly wrong for a help centre.
A practical rule: count how many distinct text levels your pages really need, then choose the largest ratio that still keeps your biggest heading at a sensible size on desktop.
Choosing the base size
16px is the browser default, and it is the right base for most sites. A few adjustments are worth considering:
- Reading-heavy sites (long articles, documentation) often set body text at 17px or 18px on desktop. The extra size improves comfort at typical reading distances.
- Interfaces with lots of data sometimes drop secondary text to 14px, but keep the main reading text at 16px.
- Font choice changes the answer. Typefaces with a large x-height (Inter, for example) look bigger at the same pixel size than ones with a small x-height (many classic serifs). Judge by eye, not by the number alone.
Whatever you choose, set it in rem, not px, in your CSS. A visitor who has increased their browser's default font size will then get larger text across the board, which is the behaviour they asked for.
A worked example: a 1.25 scale for a marketing site
Here is a complete scale built from a 16px base and a 1.25 ratio, rounded to whole pixels, with line heights and tracking for each step. This is a solid starting point for a typical landing page.
| Step | Role | Exact size | Rounded | rem | Line height | Letter spacing |
|---|---|---|---|---|---|---|
| -1 | Caption, label | 12.8px | 13px | 0.8125rem | 1.4 | 0.01em |
| 0 | Body | 16px | 16px | 1rem | 1.5 | 0 |
| 1 | Large body, lead | 20px | 20px | 1.25rem | 1.45 | 0 |
| 2 | H4, card title | 25px | 25px | 1.5625rem | 1.3 | -0.005em |
| 3 | H3 | 31.25px | 31px | 1.9375rem | 1.2 | -0.01em |
| 4 | H2, section title | 39.06px | 39px | 2.4375rem | 1.15 | -0.015em |
| 5 | H1 | 48.83px | 49px | 3.0625rem | 1.1 | -0.02em |
| 6 | Display, hero | 61.04px | 61px | 3.8125rem | 1.05 | -0.025em |
Notice what is not in the table: a 14px size, an 18px size, a 44px size. If a design asks for one of those, the honest question is whether it really needs a new step or whether an existing step will do. Nine times out of ten an existing step is fine.
Rounding is a judgement call. Some teams round to whole pixels, some to multiples of 2 or 4 so the sizes sit on the same grid as their spacing (see the spacing system guide). Small rounding errors are invisible; inconsistent rounding across components is not.
Line height: tighten as you grow
Line height (leading) is the vertical space each line occupies. The right value depends on size and line length.
- Body text: 1.4 to 1.6. Longer lines need more leading so the eye can find the start of the next line.
- Subheadings: 1.25 to 1.4.
- Large headings: 1.0 to 1.2. At 60px, a line height of 1.5 would add 30px of air between lines and make a two-line headline fall apart.
Line height also interacts with line length. A common guideline is to keep body text between about 45 and 75 characters per line. In CSS, a max-width of around 65ch on text containers gets you there without any arithmetic.
If you want body text to sit on a spacing grid, pick a line height that produces a whole multiple of 4px or 8px. 16px text at 1.5 gives 24px lines, which fits an 8-point grid neatly.
Letter spacing for display type
Most typefaces ship with letter spacing tuned for text sizes, roughly 12px to 20px. Scale the same letters up to 60px and the gaps between them scale too, so large headlines can look loose and airy in a way you did not intend.
The usual fix is a small negative tracking on display sizes:
- H2 and H1: around -0.01em to -0.02em
- Hero display sizes: around -0.02em to -0.03em
- Body text: leave it at 0, or follow the font's own guidance
Going the other way, small uppercase labels (eyebrows above headings, button text in caps, table headers) usually need positive tracking of about 0.05em to 0.1em, because capital letters set tightly at small sizes become hard to read.
Always set tracking in em rather than px, so it stays proportional when the size changes. And check your specific font: some families come with a separate display cut or optical sizing that already tightens large sizes, in which case you need less adjustment or none.
Fluid type with clamp()
A 61px hero headline is great on a laptop and too big on a 375px phone. The traditional fix was a set of breakpoints with different sizes. The modern fix is fluid type with clamp().
clamp() takes three values: a minimum, a preferred value, and a maximum. The browser uses the preferred value until it hits one of the limits.
For example, a hero headline might be written as font-size: clamp(2.5rem, 1.5rem + 4vw, 4rem). At a 400px viewport that works out to 24px plus 16px, so 40px. As the screen widens, the size grows steadily until it reaches its 64px ceiling at a 1,000px viewport, and then stays there.
A few guidelines make fluid type work well:
- Keep a rem part in the preferred value. A formula of pure
vwdoes not respond to browser zoom, which breaks a basic accessibility expectation. Mixing rem and vw keeps text zoomable. - Only make large sizes fluid. Body text at 16px to 18px can stay fixed or grow very slightly. The big headings are where fixed sizes cause trouble.
- Use two ratios. A neat approach is a smaller ratio on mobile (say 1.2) and a larger one on desktop (say 1.333), with each step clamped between its mobile and desktop value. Headings stay proportionate on small screens and gain drama on large ones.
- Test the in-between widths. Tablets and narrow laptop windows are where fluid formulas surprise you, usually with a headline that wraps onto three lines.
Matching the scale to the mood
The ratio is not only a technical decision. It sets the emotional temperature of the page. Small ratios with modest headline sizes read as calm, careful and trustworthy, which suits reassuring products like finance or healthcare. Large ratios with enormous display type feel confident and editorial, and they suit brands that want to make an entrance.
Typeface and scale also work together. A high-contrast serif at a huge size feels luxurious; the same serif in a tight 1.125 scale feels bookish. If you are still choosing fonts, the guide to Google Font pairings for websites is a good companion to this one. And if you want to see a type scale already worked out alongside a palette and spacing, every MUUDS moodboard includes a full type scale you can export as tokens or a Tailwind theme.
Common mistakes
- Too many sizes. If your CSS has fifteen font sizes, you do not have a scale. Six to nine steps cover nearly every site.
- Headings that are too close together. H3 at 22px and H4 at 20px are indistinguishable. Either widen the ratio or drop a level.
- Body text below 16px on mobile. It saves space and costs readability.
- One line height for everything. A universal 1.5 makes headlines loose and gappy.
- Fluid type without a maximum. Without a ceiling, a headline on a 2,560px monitor becomes absurd.
In short
Pick a base of 16px, choose a ratio that matches how many heading levels you need and how loud the brand should be, and round the results into six to nine named steps. Give each step its own line height and tracking, make the large steps fluid with clamp(), and set everything in rem. Then stick to the scale: the discipline of saying no to a fifteenth font size is what makes the typography feel designed.
Questions, answered
What is a good type scale ratio for a website?
For most websites a ratio between 1.2 and 1.333 works well. Use 1.2 for text-heavy products and dashboards where many heading levels must stay close, and 1.25 to 1.333 for marketing pages that need clear contrast between headings and body.
What base font size should I use for body text?
16px (1rem) is the standard browser default and a safe base for body text. Many reading-focused sites go up to 17px or 18px on desktop for comfort, but going below 16px for main body copy makes text harder to read on phones.
What line height should body text have?
Body text usually reads best with a line height between 1.4 and 1.6. Large headings need much tighter leading, around 1.0 to 1.2, because the gaps between lines grow with the font size.
How do I make font sizes responsive with clamp()?
Write each size as clamp(minimum, preferred, maximum), where the preferred value mixes rem and vw, for example clamp(2.5rem, 1.5rem + 4vw, 4rem). Keeping a rem part in the preferred value means the text still grows when a visitor zooms.
Should headings have negative letter spacing?
Large display sizes often look better with slightly negative tracking, around -0.01em to -0.03em, because default spacing is tuned for text sizes. Small uppercase labels go the other way and usually need positive tracking, around 0.05em to 0.1em.
typographytype scaleweb design


