Two pieces of software can look identical from the outside — a little widget that changes how a page looks — and be opposite things underneath.
One of them starts from what you already chose and hands you a way to adjust it. The other decides it knows better and paints over the top.
We ship the first kind. We refuse the second. This page is the test we use to tell them apart, because from a screenshot you cannot.
The test
Three questions. A control that defers answers all three the same way.
Where does the default come from? From the reader. Their operating system, their browser, the settings they configured once and forgot about years ago. Not from us, and not from a preference we think is nicer.
What happens when the reader has already decided? Nothing. We do not ask again, we do not nag, and we never overwrite. A visitor who set dark mode at the system level should never have to set it again here.
What happens when our code fails? The reader keeps what they had. A deferring control that breaks leaves the page in the reader’s own settings. An overriding layer that breaks leaves the reader stranded inside ours.
That third question is the one people skip, and it is the one that separates the two objects most cleanly. Ask what your control does when it is broken, not when it works.
Why this is not a fine distinction
Overlays are the pure case of the second kind: third-party JavaScript that loads over a site and claims to fix accessibility automatically. They do not repair the code underneath. They layer over it, and in the process they routinely break screen readers, keyboard navigation, and the settings a Disabled person spent real effort getting right.
We have written about that elsewhere and won’t repeat it here — Why We Don’t Use Accessibility Overlays has the evidence and the sources.
The part worth carrying into design work is the shape of the mistake. An overlay is not bad because it is a widget. It is bad because it inserts itself between a person and the tools they already use, and asserts authority over settings that were never ours. Anything can be built in that shape. A theme can. A plugin can. A perfectly well-meant accessibility feature can, if it starts from what we prefer instead of what the reader configured.
The failure is not the widget. It is the override.
Our controls, against the test
The Reading Experience panel in our header carries three controls. Each one exists because it passes the test.
Theme — light, dark, or auto. Auto is the default, and auto means your operating system decides. The panel starts from your setting; the manual option exists only because sometimes a person wants something different from what their OS says today.
Reading font — eight choices, because there is no single font that works for everyone and any site claiming otherwise is guessing. We picked a house default and made it trivially replaceable.
Text size — four steps, scaling up from whatever your browser is already set to. If you have raised your default text size, we build on that number rather than resetting you to ours.
And one control we deliberately did not build: motion. Designing for Motion explains why — the operating system already has that switch, we honor it, and after we turned off every animation on the site there was nothing left for a toggle to toggle. Passing the test sometimes means shipping nothing.
The third option is usually the right one
When a reading need comes up, there are three moves, and we reach for them in this order:
- Build it into the structure, so no control is needed. Semantic markup, real headings, a layout that works at 200% zoom, forms that behave. Access that requires no discovery is access that reaches everyone, including the people who will never find a settings panel.
- Point at the switch the reader already owns. Listening, translation, magnification, voice control, captions — the browser and the operating system do all of it, for free, better than we could, and everywhere, not only on our site. Our whole Accessibility Field Guide exists to do this: ear-reading, translation, live captions. We retired our own audio player and our own translation plugin to get out of the way of better tools that were already installed.
- Only then, build a control — and only where there is no device-level equivalent.
Most teams start at 3. That is how sites accumulate widgets that duplicate, and then fight, the settings people already have.
Put the control where the difficulty happens
A control that defers can still be useless if it is in the wrong place.
Russell Barkley’s point of performance is the real-life moment where a person is actually having the difficulty. Support delivered there works. The same support delivered somewhere else, earlier, in a settings screen nobody visits, mostly does not.
This is why our reading controls sit in the header of every page rather than on a preferences page. Your capacity is not fixed. It changes with the hour, the light, the migraine, the day. A person who was fine at 9am may need larger text at 4pm, and the control has to be within reach at 4pm, not filed somewhere they would have had to anticipate needing it.
Toolbelt Theory says the same thing from the learner’s side: people assemble their own solutions based on the task, the environment, and their skills and capabilities at that time. All three of those move. A control that assumes they are stable is a control designed for somebody who does not exist.
A worked example, from outside our own site
WordPress recently turned on infinite scrolling in the Media Library by default, with an opt-out placed in the user profile screen.
Asked whether the answer was a canonical accessibility plugin that could hold this and similar toggles, our position was no, and the reasoning is this page in miniature:
A plugin is the wrong shape for this. Bundling a feature’s off switch into a separate add-on makes access an extra thing to find, install, and maintain — the same posture as an overlay, just better mannered. The switch belongs in core, next to the feature, where the feature is being used. Not in a profile screen two navigations away from the media modal where the scrolling is actually happening.
That is the point-of-performance argument applied to somebody else’s software. A toggle in the media modal defers — it meets the person where the difficulty is. A toggle in a user profile technically exists. So does a plugin. Existing is not the standard.
We also think infinite scrolling is worth avoiding for the ordinary reasons, and that a toggle for it is a bandage on a structural problem that deserves a structural fix. But the toggle is the right kind of bandage, in the right place, which is more than most software manages.
In short
Build access into the foundation. Where a control genuinely helps, make it start from what the reader already chose and never overwrite it. Where the reader’s own device does the job better, document the switch and get out of the way.
A control that defers treats the reader as the authority on their own bodymind. A layer that overrides treats them as a problem it has solved. Those are different objects, and no amount of good intention converts one into the other.
