Type something to search...
Accessible Typography: Font Size, Contrast, and Spacing Guidelines

Accessible Typography: Font Size, Contrast, and Spacing Guidelines

Most accessibility work on a website involves text. Navigation labels, form instructions, error messages, article bodies, button captions: if people can't read them, nothing else about the interface matters. Yet typography decisions are often made purely on looks. Light gray text on white feels elegant in a mockup, a 13px body size looks tidy on a 27-inch monitor, and tight line spacing makes a layout feel compact. Each of those choices can lock out a real group of readers.

Accessible typography means text that people with low vision, color vision deficiencies, dyslexia, cognitive disabilities, or simply a phone in bright sunlight can read and adapt to their needs. This guide covers the Web Content Accessibility Guidelines (WCAG) requirements that apply to text, explains what each one actually asks for, and gives practical defaults for size, contrast, spacing, and line length.

What WCAG Says About Text

WCAG doesn't prescribe a font or a minimum font size. Instead, it sets requirements on contrast, resizing, spacing, and presentation. These are the success criteria that matter most for typography:

CriterionLevelWhat it requires
1.4.3 Contrast (Minimum)AA4.5:1 for normal text, 3:1 for large text
1.4.4 Resize TextAAText can be resized up to 200% without loss of content or functionality
1.4.5 Images of TextAAUse real text instead of images of text, with limited exceptions
1.4.6 Contrast (Enhanced)AAA7:1 for normal text, 4.5:1 for large text
1.4.8 Visual PresentationAAAControls over blocks of text: line width, alignment, spacing, colors, resizing
1.4.10 ReflowAAContent works at 320 CSS pixels wide without horizontal scrolling for vertical-scrolling content
1.4.11 Non-text ContrastAA3:1 for UI component boundaries and meaningful graphics
1.4.12 Text SpacingAANo loss of content when users increase line, paragraph, letter, and word spacing

Most organizations target Level AA, which is also the level referenced by many accessibility laws and procurement standards. The AAA criteria are still worth knowing, because they describe what genuinely comfortable reading looks like. You can read the full text of each criterion in the WCAG 2.2 specification.

Contrast

Contrast is the most frequently failed typography requirement on the web, and it's also the easiest to measure.

The Ratios

WCAG measures contrast as a ratio between the relative luminance of the text color and the background color, from 1:1 (no contrast) to 21:1 (black on white).

  • Normal text needs at least 4.5:1 for AA, and 7:1 for AAA.
  • Large text needs at least 3:1 for AA, and 4.5:1 for AAA.

"Large" has a specific definition: at least 18 point, or at least 14 point if bold. WCAG notes that these point sizes correspond roughly to 24px and 18.66px respectively in CSS. So a 20px heading at normal weight isn't large text by this definition, and needs the full 4.5:1.

Common Failures

The most common contrast failures are design trends:

  • Light gray body text like #999999 on white, which is about 2.8:1.
  • Placeholder text in form fields, which browsers render faintly by default and designers often lighten further.
  • Text on images, where contrast changes across the image.
  • Brand colors used for links or buttons without checking contrast against the background.
  • Disabled-looking text that isn't disabled, such as secondary metadata styled at low opacity.

For reference, here are a few grays on a white background:

Text colorApprox. ratio on #ffffffPasses AA normal text?
#9999992.8:1No
#7676764.5:1Yes, just barely
#5959597.0:1Yes, and AAA
#33333312.6:1Yes

#767676 is a widely used value because it's about the lightest gray that passes 4.5:1 on white. If your design system's "muted" text color is lighter than that, it's failing.

Defining Accessible Color Tokens

Bake contrast into your tokens so individual components can't drift:

:root {
  --color-bg: #ffffff;
  --color-text: #1e293b;
  --color-text-muted: #475569;
  --color-link: #0369a1;
  --color-border-input: #64748b;
}

body {
  background: var(--color-bg);
  color: var(--color-text);
}

.meta {
  color: var(--color-text-muted);
}

input,
select,
textarea {
  border: 1px solid var(--color-border-input);
}

::placeholder {
  color: #64748b;
  opacity: 1;
}

The opacity: 1 on ::placeholder is a safeguard: some browsers have applied reduced opacity to placeholders by default, which lowers the effective contrast of whatever color you choose.

Input borders fall under 1.4.11 Non-text Contrast, which requires 3:1 for the visual boundary of a control. A very light border on a white input can fail even when the text inside passes.

Remember to check every theme. Dark mode has its own failure patterns, especially pure white text on pure black, which some readers find causes halation. See typography in dark mode for adjustments beyond color.

Font Size

WCAG has no minimum font size. What it does require is that users can enlarge text: 1.4.4 says text must be resizable up to 200% without assistive technology and without loss of content or functionality. In practice that means:

  • Use relative units like rem for font sizes so they respect the user's default font size setting.
  • Avoid fixed-height containers that clip enlarged text.
  • Don't disable zoom on mobile with maximum-scale=1 or user-scalable=no in the viewport meta tag.
<!-- Good -->
<meta name="viewport" content="width=device-width, initial-scale=1" />

<!-- Bad: blocks pinch-zoom -->
<meta
  name="viewport"
  content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
/>

Why px font sizes cause trouble for users who change their browser's default size is covered in detail in respecting user font size preferences.

Practical Size Defaults

Even without a WCAG minimum, there are sensible defaults:

  • Body text: at least 1rem (16px at default settings). Many reading-focused sites use 17 to 20px.
  • Secondary text like captions and metadata: avoid going below 0.875rem (14px), and make sure it still meets 4.5:1 contrast.
  • Form inputs: at least 1rem. On iOS Safari, inputs with a font size under 16px trigger an automatic zoom when focused, which is disorienting.
  • Legal and fine print: small text is still text that people need to read. Don't drop it below 12px, and keep the contrast high.
html {
  font-size: 100%;
}

body {
  font-size: 1.0625rem;
  line-height: 1.6;
}

small,
.caption {
  font-size: 0.875rem;
}

input,
select,
textarea,
button {
  font: inherit;
  font-size: max(1rem, 1em);
}

The font: inherit line fixes a long-standing browser default where form controls use a smaller system font instead of the page's font.

Spacing

Line Height

WCAG 1.4.8 (AAA) asks for line spacing of at least space-and-a-half within paragraphs, which in CSS terms is a line-height of about 1.5. That's a good default for body text even if you're targeting AA. Headings can be tighter, because they're short and set larger:

body {
  line-height: 1.6;
}

h1,
h2 {
  line-height: 1.15;
}

h3,
h4 {
  line-height: 1.3;
}

Always use unitless line heights. A value like 24px doesn't scale when the text grows, which leads to overlapping lines at 200% text size. For more detail, see how to choose the right line height for body text.

Letter and Word Spacing

You rarely need to add letter spacing to body text, but you must make sure your layout survives if users do. WCAG 1.4.12 Text Spacing (AA) requires that no content or functionality is lost when users set:

  • Line height to at least 1.5 times the font size
  • Spacing after paragraphs to at least 2 times the font size
  • Letter spacing to at least 0.12 times the font size
  • Word spacing to at least 0.16 times the font size

This doesn't mean you have to use those values. It means your components must not clip, overlap, or hide text when a user applies them with a bookmarklet, browser extension, or user stylesheet. The most common culprits are fixed heights and overflow: hidden. The full testing process is in meeting WCAG text spacing requirements.

Paragraph Spacing

Clear gaps between paragraphs help everyone find their place, and WCAG 1.4.8 suggests paragraph spacing at least 1.5 times the line spacing. A bottom margin of around 1em to 1.5em on paragraphs is typical.

Line Length and Alignment

WCAG 1.4.8 (AAA) recommends lines no wider than 80 characters (40 for Chinese, Japanese, and Korean) and text that isn't justified. Both recommendations reduce the effort of tracking from the end of one line to the start of the next.

.article-body {
  max-inline-size: 70ch;
}

.article-body p {
  text-align: start;
}

Justified text creates uneven gaps between words, sometimes forming "rivers" of white space that are especially hard for readers with dyslexia. Left-aligned (or start-aligned) text with a ragged right edge keeps word spacing consistent.

Font Choice and Style

WCAG doesn't require any particular typeface, but some choices clearly help:

  • Distinguishable letterforms. Look for fonts where uppercase I, lowercase l, and the digit 1 look different, and where 0 and O are distinct. This matters for codes, passwords, and reference numbers.
  • A generous x-height. Fonts with taller lowercase letters stay legible at smaller sizes. What is x-height explains why.
  • Real text, not images of text. Images can't be resized cleanly, recolored, or reflowed. 1.4.5 asks you to use real text except where a particular presentation is essential, like a logo.
  • Restraint with italics, all caps, and underlines. Long passages of italic or uppercase text are harder to read. Use bold or a heading for emphasis, and keep underlines for links.
  • Readable weights. Very thin weights (100 to 300) can disappear at small sizes, especially on low-resolution screens or with reduced contrast.

Supporting User Preferences

Accessible typography also means letting users' own settings win:

@media (prefers-contrast: more) {
  :root {
    --color-text-muted: #1e293b;
    --color-border-input: #1e293b;
  }
}

@media (forced-colors: active) {
  .badge {
    border: 1px solid CanvasText;
  }
}

prefers-contrast: more lets you tighten up muted colors for people who've asked their operating system for more contrast. forced-colors: active detects modes like Windows Contrast Themes, where the browser replaces your colors with a user-chosen palette. In those modes, backgrounds disappear, so anything that relied on a background color to look like a badge or button needs a border.

Readers with dyslexia often benefit from specific adjustments too; designing text for users with dyslexia covers those.

Common Mistakes

  • Using a gray lighter than about #767676 on white for body text, metadata, or placeholders.
  • Treating 20px as "large text" for contrast purposes. Large means roughly 24px regular or 18.66px bold.
  • Setting font sizes in px, which ignores the user's default font size.
  • Blocking zoom with user-scalable=no or maximum-scale=1.
  • Fixed line heights in px, which cause lines to overlap when text is enlarged.
  • Fixed-height containers with overflow: hidden, which clip text when users increase spacing or size.
  • Checking contrast only in the light theme, or only on solid backgrounds when text sits over images or gradients.
  • Justified body text in narrow columns, creating uneven word spacing.

Conclusion

Accessible typography comes down to a handful of measurable rules: 4.5:1 contrast for normal text and 3:1 for large text, text that resizes to 200% without breaking, layouts that survive increased spacing, and readable defaults for size, line height, and line length. WCAG sets the floor, and comfortable reading usually sits a little above it.

Start by encoding the rules in your design tokens: accessible text colors, rem-based sizes, unitless line heights, and a ch-based measure. Then test with real settings: zoom to 200%, change the browser's default font size, and apply a text spacing bookmarklet. Those three checks catch most typography accessibility problems before your users do.

Share :

Related Posts

A Short History of Typography: From Gutenberg to Variable Fonts

A Short History of Typography: From Gutenberg to Variable Fonts

When you write font-weight: 600 or font-style: italic, you're using vocabulary that is hundreds of years old. "Italic" comes from Renaissance Ita

Continue Reading
Bauhaus Typography and Its Influence on Modern Design

Bauhaus Typography and Its Influence on Modern Design

Bold sans-serif type, thick black bars, red accents, text running at an angle, and lowercase-only headlines. If a poster or website uses that combina

Continue Reading
Building a Reliable System Font Stack

Building a Reliable System Font Stack

The fastest font on the web is the one that's already on the reader's device. No download, no @font-face, no flash of invisible text, no layout shi

Continue Reading