Of all the WCAG success criteria, 1.4.12 Text Spacing is the one most often waved through. It asks that nothing be lost when a reader overrides four properties: line height at least 1.5 times the font size, space after a paragraph at least 2 times the font size, letter spacing at least 0.12em and word spacing at least 0.16em. People who need those settings use an extension or a user stylesheet to get them, and if your layout assumes its own leading, their reading experience is text sliced in half by a box that will not grow.
It is also one of the few criteria you can test exhaustively with no judgement calls at all. Four declarations, injected, then measure. So I ran it over all 76 public pages of Nakodo and compared each page with itself.
The injection
One stylesheet, appended to the head, with the four properties at !important so nothing in the cascade can refuse them:
const s = document.createElement("style"); s.textContent = `*,*::before,*::after{ line-height:1.5 !important; letter-spacing:0.12em !important; word-spacing:0.16em !important } p{margin-bottom:2em !important}`; document.head.appendChild(s); Applying it to * rather than to body text is deliberate. The criterion is about what a reader's override does, and a reader's override does not politely skip your buttons, badges and table cells. If a 36px high button holds text that suddenly wants 1.5 line height, I want to know.
Then, before and after on each page, I collected two things. First, every element that is clipping: a computed overflow of hidden, clip, auto or scroll combined with a scrollHeight greater than its clientHeight, or the same in the horizontal. Second, every element whose text escapes its own box, found by selecting the element's contents with a Range and comparing the range's rect with the element's rect, which catches content spilling out of a box that is not clipping it.
Comparing before with after is the part that matters. A site always has a few elements that clip on purpose, and a tool that reports those as failures teaches you to ignore it.
The result
Zero newly clipped elements across 76 pages. No page gained a horizontal scrollbar. None had one to begin with.
The count of clipping elements went the other way, from 105 down to 29. The reason is pleasing. 76 of those 105 are one element: the site footer, which has overflow-hidden because a drawn landscape sits behind it at 10 per cent opacity and must not stick out of the bottom of the page. When every paragraph above it grows, the footer grows, the scenery fits, and the only element on the page whose clipping was doing real work stops clipping at all.
The 29 that remain were clipping before the override as well:
- 10 are
sr-only, which is a 1px box with clipping as its entire mechanism. Flagging those is the tool working correctly on a pattern that is correct. - 18 are a metadata row with
leading-none, over by a pixel or two in both measurements. - 1 is a display heading in the same state before and after.
The escape check came back identical before and after: three per page, every page. Two of them are the wordmark, whose text range is 37px tall in a 33px box because the font's ascenders exceed the line box, and one is a decorative illustration positioned against the bottom of a section. Neither moves when the spacing changes.
69,833 extra pixels
Passing does not mean nothing happened. Added up across the site, the documents went from 423,816 pixels of height to 493,649. That is 69,833 more pixels, or 16.5 per cent more page.
Per page, the median growth is 16.2 per cent. The spread is wide:
That spread is the interesting part, because it is not about how much text a page has.
Which of the four properties actually costs anything
I ran the four declarations separately on three pages. The results were not what I expected from a criterion everybody files under "line height".
| Override | /guides | /glossary | a guide page |
|---|---|---|---|
line-height: 1.5 | 2.1 per cent shorter | 8 per cent shorter | 4.7 per cent shorter |
letter-spacing: 0.12em | 12.6 per cent taller | 14 per cent taller | 10.9 per cent taller |
word-spacing: 0.16em | 1.8 per cent taller | 3.2 per cent taller | 1.7 per cent taller |
p { margin-bottom: 2em } | 16.8 per cent taller | 1 per cent taller | 9.7 per cent taller |
The line-height rule shrinks every page it touches. 1.5 is a floor, and this site is already well above it. Sampling 40 paragraphs in one guide's main, the computed metrics are 15px text on a 28px line in 15 of them and 15 on 24 in another 16, which is a ratio of 1.87 and 1.6. Forcing 1.5 is a reduction, not an increase, for 31 of 40 paragraphs. The ones it genuinely helps are the 11 and 12px captions sitting at 1.33 and 1.45.
That is worth saying plainly, because the way the criterion is usually described ("make sure 1.5 line height does not break your layout") implies the test adds vertical space. On comfortable typography it removes some, and the real cost lands elsewhere.
Letter spacing is the expensive one. 0.12em on every character reflows paragraphs into more lines, and that is 10 to 14 per cent of page height on every page measured. It is also the property least likely to be in anyone's test setup, because adding tracking looks harmless written down.
The paragraph rule explains the whole spread. The guides hub has 68 p elements, so 2em after each one is 16.8 per cent of its height. The glossary has 11 paragraphs and 27 dd elements, because a glossary is a description list rather than a sequence of paragraphs, and p { margin-bottom: 2em } barely touches it. The least affected page on the site is the one that is not built out of paragraphs.
Why it passes
There is no clever work behind this result, which is the useful thing to report. Three ordinary habits did it:
- Almost nothing on the site has a fixed height with text inside it. Buttons are 36px with 14px text, so a 21px line box still fits. Cards and panels size to content. The one fixed-height thing with text inside is the metadata row that was already a pixel over.
-
overflow: hiddenis on decoration, not on text. The footer clips a drawing. Nothing on the site clips a sentence, so there is nowhere for text to be lost. - Containers cap width, not height. Pages are flow layout inside
max-w-*containers, so the only thing that happens when the text gets bigger is that the page gets longer, which is the thing a browser is actually good at.
Try it on this site
Paste this into the console on any page of nakodo.app and watch the document grow without anything being cut off:
const h = document.documentElement.scrollHeight; document.head.insertAdjacentHTML("beforeend", `<style>*,*::before,*::after{line-height:1.5!important;letter-spacing:.12em!important;word-spacing:.16em!important}p{margin-bottom:2em!important}</style>`); setTimeout(() => console.log(h, "->", document.documentElement.scrollHeight), 300); For the version that finds failures, add the clipping check and run it before and after:
[...document.querySelectorAll("body *")].filter((el) => { const cs = getComputedStyle(el); return ["hidden", "clip", "auto", "scroll"].includes(cs.overflowY) && el.scrollHeight > el.clientHeight + 1; }).map((el) => el.className); On the guides hub that returns one element before the override, which is the footer, and none after.
What I am taking away
Nothing to fix, which is the rarest outcome of a sweep like this. Two things to keep, though.
Put the four declarations in a snippet and run them when you build anything with a fixed height around text. The failures this criterion catches are specific: pill badges with hardcoded heights, single-line truncated labels, tab bars, anything with leading-none and a h- class in the same string.
And stop thinking of 1.4.12 as the line-height criterion. On this site the line-height clause gave pages back 2 to 8 per cent of their height, and the one that cost real layout was letter spacing, which nobody tests.