Units and accessibility

Readers enlarge text in two different ways, and a unit that handles one can ignore the other. This guide says which does what, measured in Chromium.

The three criteria, in plain words

Criterion 1.4.4, titled Resize Text, asks that text can be enlarged to 200% by the browser without losing content or function. Criterion 1.4.10, titled Reflow, asks that a page works at a width of 320 CSS pixels without scrolling in two directions, which is what a 1280px window shows at 400% zoom. Criterion 1.4.12, titled Text Spacing, asks that nothing gets lost when a reader sets the line height to 1.5 times the text size, paragraph spacing to 2 times, letter spacing to 0.12 times and word spacing to 0.16 times.

All three are Level AA. They are about what a reader does to your page, so a page can follow every rule of its own CSS and still fail them. The sections below are about the units that decide the outcome.

Two ways to enlarge: zoom the page, or raise the default size

Page zoom scales every CSS length, px included, and makes the window narrower in CSS pixels: at 200% a window 1280px wide holds 640 CSS pixels, so min-width queries fire as if on a smaller screen. Nothing in the stylesheet has to cooperate.

Raising the default font size in the browser settings is a different action and reaches much less. It changes the root font size, so it moves rem, em and breakpoints written in em. It leaves every absolute unit alone, px and pt among them. In Chromium with the default raised from 16px to 24px, 1rem became 24px while 1px stayed 1px.

Many readers use the second setting and never touch zoom, because it enlarges text on every site at once. A page built in px ignores them. A page that sets html { font-size: 16px } ignores them too: the root size in pixels switches the setting off.

What follows the reader's default size and what does not
.fixed { font-size: 16px; padding: 8px; }   /* 16px and 8px at any setting */
.fluid { font-size: 1rem; padding: 0.5em; }  /* 24px and 12px when the reader asks for 24px */

Units that break under enlargement

Text sized in vw alone does not grow with page zoom. Zoom narrows the window in CSS pixels, so 4vw shrinks by the factor the page grows by and the text keeps its size on screen. Adding a rem term helps only in part: calc(1rem + 2vw) came out about 1.4 times larger at 200%, and clamp(1.5rem, 1rem + 2.5vw, 3rem) about 1.33 times. Criterion 1.4.4 asks for 200%, so test the formula you ship at that zoom instead of trusting the arithmetic.

A fixed height on a box of text clips it. A paragraph of three lines in a box 72px tall, with overflow: hidden, lost its last lines when the default size went from 16px to 24px. The same box written as 4.5rem held all three, because the box grew with the text. Use min-block-size and let content decide the height wherever you can.

Breakpoints in px stay where they are when the reader raises the default size, which keeps a desktop layout on a screen that now needs the narrow one. In em, the breakpoint moves with the reader: 40em switched at 640px for the default and at 960px once the default was 24px. An em in a media query always means the browser's own default, so a font-size you set on html does not shift it.

Line height and spacing that keep up

Write line-height as a plain number. A number is inherited as a ratio, so a child with larger text gets lines to match. A percentage or an em is turned into a length before it is inherited, so the child keeps the parent's line height and larger text can crowd it.

Criterion 1.4.12 is the reason to leave room. A box with a fixed height or overflow: hidden loses text the moment a reader sets the spacing it names, so give text containers room to grow in the block direction.

How to test a page

Four checks, in the order they catch things. Make the window 320px wide and scroll down: nothing but a data table may scroll sideways. Zoom to 200% in a 1280px window and do it again. Then open the browser settings, set the default font size to 24px and reload: text that is clipped, buttons whose labels wrap out of sight and boxes with a fixed height show up now. Last, apply the four spacing values of criterion 1.4.12 with a user stylesheet and read the page once more.

This site runs the second and third automatically. Every unit page is loaded at 320px with the root font size at 100% and at 200%, left to right and right to left, and the test fails on any sideways scroll. A separate test sets the four spacing values and checks that no text is lost.

What this guide does not cover

The numbers here come from Chromium. Firefox and Safari zoom and apply the default size in their own way, and this guide has not measured them. No screen reader has been used on this site yet, and none of this replaces testing with people who use a page enlarged for long periods.