Font size is the single setting with the biggest effect on readability, and it is also the one most often set too small. This guide explains how to choose a base size for body text, how to size headings consistently and how to keep text accessible across devices.

Start with the body text

Browsers use a default font size of 16 pixels, and that is a sensible minimum for body text on the web. Many content-focused sites use 17 to 20 pixels for paragraphs, because readers often hold phones at arm’s length or sit back from large monitors. As a starting point:

  • 16px for interfaces, dashboards and dense content;
  • 17–18px for general websites and blogs;
  • 18–20px for long-form reading.

Smaller text, around 13–14px, can work for captions, labels and legal notes, but should not be used for anything people need to read at length.

Pixels are not the whole story

Two fonts set at the same pixel size can look very different in size. The visible size of lowercase text depends largely on the x-height, the height of letters such as x and a. A font with a large x-height, such as Inter or Merriweather, looks bigger at 16px than a font with a small x-height, such as Cormorant Garamond or Josefin Sans. The Font Comparison tool measures the x-height ratio for each font so you can compare them directly.

When switching fonts, re-check the size rather than reusing the previous number.

Use rem units

Some visitors increase their browser’s default font size because they find text hard to read. If you set sizes in pixels, their preference is ignored. If you set them in rem, which is relative to the root font size, text scales with their setting.

html { font-size: 100%; }   /* respect the browser default */
body { font-size: 1.125rem; } /* 18px when the default is 16px */
h1   { font-size: 2.5rem; }   /* 40px */

Avoid setting the root to a fixed pixel value such as html { font-size: 10px; }, which overrides the visitor’s choice.

Size headings with a scale

Choosing heading sizes one by one tends to produce sizes that are too similar or randomly spaced. A modular scale multiplies the base size by the same ratio for each step. With an 18px base and a ratio of 1.25:

ElementCalculationSize
Small text18 ÷ 1.2514.4px
Body1818px
h418 × 1.2522.5px
h318 × 1.25²28.1px
h218 × 1.25³35.2px
h118 × 1.25⁴43.9px

Smaller ratios such as 1.125 or 1.2 suit applications and dense layouts. Larger ratios such as 1.333 or 1.5 create dramatic, editorial pages. The Website Typography Preview lets you switch ratios and see the result on a full page.

Make headings responsive

A 44px heading that looks balanced on a laptop can take up half of a phone screen. Two common approaches:

  1. Use a gentler ratio on small screens with a media query.
  2. Use fluid sizes with clamp(), which grows the size with the viewport between a minimum and a maximum.
h1 {
  /* at least 2rem, at most 3rem, fluid in between */
  font-size: clamp(2rem, 1.4rem + 2.5vw, 3rem);
}

When using clamp(), include a rem component in the preferred value, as above, so that the text still grows when visitors zoom or change their default size.

Accessibility checkpoints

  • WCAG 2 success criterion 1.4.4 asks that text can be resized up to 200% without loss of content or function. Relative units and flexible layouts make this much easier.
  • Contrast requirements depend on size: 4.5:1 for normal text and 3:1 for large text (roughly 24px regular or 18.66px bold). The Font Playground shows the ratio as you choose colours.
  • Do not disable zoom on mobile with maximum-scale=1 or user-scalable=no.

Font size works together with line height and line length. Continue with line height and letter spacing explained.