Skip to content
UI/UX2 July 2026 · By the Intense Path Editorial Team

Accessibility as a Default: What to Build Before the Audit

Accessibility retrofits are expensive because they change structure, not styling. Decide semantics, focus, contrast, target size and motion at build time and the audit becomes a check rather than a rescue.

On This Page
Pass It On

Found this useful? Send it to someone who’s building.

Accessibility by Default: Build Before the Audit | Intense Path

The audit arrives with sixty-one issues and a deadline. Read it properly and forty of them are the same three mistakes repeated across a component library, and the fix for each is structural rather than cosmetic, which means every screen built on those components has to be reopened. That is the bill for treating accessibility as a review step.

The argument here is narrow and practical. Accessibility by default is cheaper than remediation and it delivers more. Not because remediation is technically hard, but because it happens after the structure has set, and by then the cheap fixes have already been ruled out.

Nothing that follows is exotic. Five decisions cover most of it: semantics, focus, contrast, target size and motion. Each costs close to nothing while a component is being written, and each becomes a project once a hundred screens depend on it. The criteria themselves live in WCAG 2.2; what follows is where they land in a build, and when to make each call.

The retrofit tax

Remediation is expensive for one specific reason, and it is not effort. It is that the cheapest available fix has already expired.

Take a single control. A dropdown assembled from divs and click handlers works acceptably with a mouse. Making it keyboard-operable afterwards means adding roles, managing focus, implementing arrow-key behaviour, handling Escape and writing the tests that stop the next release breaking it again. The same control built on a native element inherits all of that for the price of typing a different tag name. One outcome, two very different weeks of work.

This is a genuine category of debt, and unlike some kinds it does not sit still. Every new screen built on the same component multiplies the eventual fix, which is worth remembering when deciding which technical debt to keep and which to pay now. Structural accessibility debt belongs firmly in the second group.

The decisionCost at build timeCost when retrofitted
Use a native button rather than a styled divA tag nameRoles, keyboard handling and tests, per component
Keep a visible focus stateNothing at allRedesigning every interactive state after review
Define contrast as token pairsOne palette decisionEditing every component that inherited a bad pair
Give each field a real labelOne elementRewriting forms and the tests that asserted on placeholders
Reserve target size in the spacing scaleA spacing ruleReflowing dense layouts on small screens
Honour reduced motion globallyOne media queryAuditing every animation on its own
Write headings in document orderOrdinary disciplineRestructuring templates that used headings for size

Accessibility is not a feature added to a page. It is a property of the decisions the page was already built from.

Semantics: the decision the other four rest on

Semantics decides how much behaviour you inherit instead of writing. Get it right and focus, states and keyboard operation arrive largely finished. Get it wrong and each of them becomes a separate implementation with its own bugs and its own regression risk.

Native elements first

  • Keyboard behaviour you did not write. A button sits in the tab order and responds to both Enter and Space. A div does none of that until somebody remembers, and somebody usually remembers late.
  • A role the assistive layer already knows. No attribute required, because the element announces what it is without being told.
  • Platform conventions on mobile. Native form controls bring the correct keyboard, the correct picker and the autofill behaviour people already rely on.
  • States as properties, not class names. Disabled, checked, required and invalid are real states other software can read, rather than styling you happen to apply.
  • Behaviour that survives your JavaScript failing. A native details element still opens when a bundle does not load. A custom accordion becomes a paragraph nobody can reach.

The corollary is unpopular inside component libraries: do not add ARIA to an element that is already semantic. The ARIA documentation is blunt about this, and the first rule remains to use the native element instead. Extra roles layered onto a correct element usually make the announcement worse rather than richer.

Headings are structure, not typography

When somebody picks a level three heading because it is the right size, the document outline stops describing the page and screen reader users lose the fastest route through it. One page-level heading, a logical order underneath it, and a type scale generous enough that a designer can make a second-level heading small when the layout wants it. That is a systems problem more than a discipline problem, and it is one of the reasons a design system earns its keep earlier than most teams expect.

Landmarks do the same job for regions of the page. A header, a navigation region, one main element, a footer, and a skip link that genuinely moves focus rather than only moving the scroll position. Two minutes of markup replaces a great deal of tabbing.

Focus: the state most teams delete on purpose

Somebody sees an outline they did not design, removes it in a reset file, and the site stops working for everyone who does not point at things. It is the most common self-inflicted accessibility failure there is, and it stays invisible to the person who caused it, because they were holding a mouse at the time.

Design the state, do not restore the default

The fix is not to put the browser default back. Focus is a designed state exactly like hover, and it deserves the same attention: a ring, an offset, a change that reads instantly. Use the focus-visible selector so it appears for keyboard users without decorating every mouse click. Then check it against each background it can land on, including the dark band, the accent button and the photograph.

Order, trapping and return

Focus order comes from the source, not the layout. When CSS reorders elements visually and the markup disagrees, keyboard users travel a path nobody has ever seen. Modals and drawers add two more rules: hold focus inside while open, and hand it back to the control that opened them on close, with Escape available throughout. None of this needs tooling to check. Put the mouse down and try it, which is exactly the exercise in what a keyboard user experiences on your site right now.

  1. Start in the address bar and tab forward. Not from a click inside the page, which skips the part where most sites fail first.
  2. Confirm the skip link appears and works. It should become visible on focus and move focus into the main region, not merely scroll toward it.
  3. Watch for focus disappearing. If you cannot see where you are for even one stop, that stop is a failure. Note it and keep going.
  4. Open every overlay with the keyboard. Menu, drawer, modal, date picker. Check trapping, check Escape, check where focus lands afterwards.
  5. Submit a form with a deliberate error. The message has to be associated with the field and reachable without hunting, not merely coloured red beside it.
  6. Zoom the page to twice its size. Content should reflow rather than clip, and nothing should need horizontal scrolling to read.
  7. Turn on reduced motion and reload. Everything that was animated should still be present and still readable, stilled rather than removed.

Contrast belongs in the tokens, not the review

Contrast failures are the most common finding in almost any report and the most avoidable, because they are decided once in a palette and inherited everywhere afterwards. A review catching them screen by screen is a review doing a token set’s job.

So define pairs, not colours. A system that names foreground and background pairs, and states which combinations are legal, struggles to produce a failing screen. A palette listing twelve hex values and trusting everybody produces failing screens weekly. This decision belongs in product design rather than in a remediation ticket eleven months later.

Three cases slip past even careful teams. Placeholder text pressed into service as a label, which fails contrast and then vanishes the moment somebody types. Disabled states nobody ever checked, because they are meant to look faint. And text set over photography, where the contrast depends on an image somebody will swap next month. The third needs a standing rule, usually a scrim or a solid panel, decided once and applied without further argument.

There is a commercial argument too. Low-contrast interfaces look refined in a design tool and read as ambiguous on a phone in daylight, and ambiguity costs conversions long before it costs compliance. That is part of the mechanism behind a redesign that converts worse than the page it replaced.

Targets, spacing and the thumb

Target size is a spacing decision made once in the scale and then forgotten about, or it is a hundred small arguments held per screen. WCAG 2.2 sets a minimum of 24 by 24 CSS pixels, with a more generous 44 by 44 available as a higher-level criterion. We design to the larger figure, because a number that lives in the spacing scale is a number nobody has to remember.

The failure is rarely the primary button. It is a row of icon-only controls inside a table, a close button tucked into a corner, a checkbox whose label is not clickable, or two links sitting a few pixels apart in a paragraph on a phone. Spacing between adjacent targets matters as much as the targets themselves, because a thumb that lands on the wrong one has still failed the task.

Density is the usual objection, and it is a fair one. Data-heavy interfaces genuinely need to fit more on screen. The answer is not to shrink the hit area but to separate it from the visual size: a small icon with a larger invisible target around it satisfies both, and costs one padding rule in a shared component.

Motion, and the path where it is switched off

Motion is the cheapest of the five to get right and the easiest to forget, because the person who wrote the animation has never had it make them unwell. Vestibular disorders are not rare, and parallax is not a neutral choice.

One global rule covers most of it: honour the reduced-motion preference, and honour it by stilling things rather than hiding them. An instant state change is a legitimate replacement for a transition. A carousel that advances on its own needs a pause control regardless of preference, because reading speed is not something you can predict from a browser setting.

The rule we hold to without exception: content must never depend on an animation having run. A reveal that fails to trigger, on a slow connection or in a browser where the observer never fires, has to leave the words on the page anyway. Build the failsafe on the first day, because it is three lines then and a support ticket later.

What you bolt on is part of your page

Everything so far concerns code you own. Most sites also carry code they do not: a chat widget, a consent banner, a booking embed, a reviews carousel. Each one lands in the same tab order as the rest of the page and inherits none of your decisions.

Test them exactly as you test your own components. Can a keyboard user reach it, open it, use it and leave? Does it hold focus and refuse to give it back? Does the consent banner appear ahead of the skip link and block everything behind it? A widget such as Flidu, which puts website-informed AI assistance alongside contact, information and conversion actions in one lightweight component, sits inside your keyboard path whether or not it was inside the audit scope. Our parent company has written up the specific requirements in an accessible chat widget.

What an overlay cannot do for you

A script layered over a finished page cannot turn a div into a button, invent a label that was never written, or repair a heading order that never described the page. Overlays can adjust presentation. They do not change the structure assistive technology actually reads. If a tool promises compliance without touching your markup, ask which criterion is being satisfied, and how.

What the audit is actually for

None of this makes an audit unnecessary, and building carefully does not make you compliant. That is the honest limit of the argument. What building carefully removes is one whole class of finding: the unreachable control, the unlabelled field, the invisible focus ring, the heading order that describes nothing. Those are the findings that cost most to fix late, and they are the ones a component library multiplies while you are not looking.

What remains is judgement. Whether the alternative text says the useful thing rather than the literal thing. Whether the sequence through a complex widget makes sense to somebody who cannot see it. Whether the language is understandable to a person under stress. Those need people, including people who use assistive technology every day, and no amount of build-time discipline replaces them.

It does change what the report looks like. An audit of a well-built site is short, specific and mostly about content. The screens that still fail are predictable: the error state, the loading state, the print styles, and whatever was built in a hurry the week before launch. Empty states belong on that list too, since they are the least designed screen in most products and among the first a new user meets. We publish our own position on accessibility as a stated commitment, because a written standard is easier to hold a team to than a good intention.

The rule we would adopt

One condition, applied at component review: nothing enters the library until it can be operated with a keyboard, shows a visible focus state, and passes contrast in the tokens it inherits. Three checks, made once per component rather than once per screen. It is the cheapest accessibility programme available, and it works only because it moves the check to the moment when structure is still soft.

The advice reverses in exactly one situation. If a live site is failing people today, do not wait for the rebuild that would do it properly. Fix what is reachable now, which usually means labels, focus, contrast and the skip link, even knowing you will touch all of it again later. Somebody blocked this week takes no comfort from a better architecture next quarter.

Everywhere else the sequence holds: decide the five defaults, put them in the system, and let the audit confirm rather than rescue. If you are planning a build or a rebuild and want those decisions made before the components exist, tell us what you are building and which of the five you have already settled.

Take these with you
Accessibility is decided by structure, so the cheap moment to get it right is while a component is being written rather than after a report names it.
Native elements hand you keyboard behaviour, roles and states for the price of a tag name, and adding ARIA to something already semantic usually makes it worse.
Focus is a designed state, so style it instead of resetting it away, and check it against every background it can land on.
Contrast pairs and target sizes belong in the token set and the spacing scale, where one decision covers every screen instead of every screen needing a check.
Building well removes the structural failures but not the judgement calls, so an audit and testing with real assistive technology users still have work to do.

Common questions.

What does accessible by default actually mean?

It means the structural decisions that determine accessibility are made while a component is being built rather than after a report arrives. In practice that covers five things: native semantics, a visible focus state, contrast defined as token pairs, target sizes reserved in the spacing scale, and a global reduced-motion path. Each is close to free at build time and expensive to introduce afterwards.

Is it cheaper to build accessibly or to remediate later?

Building accessibly is cheaper, because remediation happens after the structure has set. Turning a styled div into a real button is a one-word edit while the component is being written, and a rewrite of keyboard handling, roles, focus management and tests once fifty screens depend on it. Remediation also repeats the same few mistakes across a library, so one bad decision becomes dozens of tickets.

Do accessibility overlays make a website compliant?

No. A script layered over a finished page cannot turn a div into a button, invent a label that was never written, or repair a heading order that never described the page. Overlays can adjust presentation, such as text size or colour, but they do not change the underlying structure assistive technology reads. Treat any promise of compliance without markup changes with real suspicion.

What is the minimum target size for a touch control?

WCAG 2.2 sets a minimum of 24 by 24 CSS pixels at level AA, and a more generous 44 by 44 as a higher-level criterion. Designing to the larger figure is simpler, because it can live in the spacing scale instead of being checked component by component. The usual failures are icon-only controls in dense table rows and close buttons tucked into corners.

How do I test keyboard accessibility without special tools?

Put the mouse away and tab through the page starting from the address bar. Check that focus is always visible, that the order follows the visual layout, that the skip link works, that overlays trap focus and return it on close, and that Escape closes whatever opened. That single pass finds more real problems than most automated scans, which cannot judge order or visibility.

Does honouring reduced motion mean removing all animation?

No. It means respecting a stated preference by stilling motion rather than hiding content. Replace movement with an instant state change, keep any remaining transition short and free of parallax, and never let content depend on an animation having run. If a reveal fails to trigger for any reason, the text still has to be on the page, which is a build requirement rather than a preference setting.

Who should own accessibility in a small team?

In a small team it belongs to whoever reviews components, because that is the moment structure is still cheap to change. Making it a review condition works better than making it one person’s responsibility: nothing enters the library until it is keyboard-operable, shows a visible focus state and passes contrast in its inherited tokens. Three checks at review beat one audit at the end.

Facing this in your
own business?

Tell us where you’re headed — we’ll map the shortest honest route.

Start a Project