Accessibility isn't a compliance checkbox, and treating it like one shows
Accessibility work often gets treated as a final compliance pass: run an automated scanner, fix whatever it flags, done. Automated scanners genuinely help, and they also only catch a fraction of real accessibility issues, the ones that are structurally detectable. The issues that actually affect real users with disabilities most often require judgment a scanner can't apply.
What automated scanners catch, and what they miss
Tools like axe or Lighthouse's accessibility audit reliably catch missing alt text, insufficient color contrast, and missing form labels, all genuinely valuable checks. They don't catch whether alt text is actually meaningful and descriptive versus technically present but useless ("image1.jpg"), whether a genuinely logical tab order exists through a complex interactive component, or whether an interaction actually makes sense to someone using a screen reader rather than looking at the screen.
Testing with an actual screen reader, not just a scanner
We do a manual pass through key user flows using a real screen reader (VoiceOver or NVDA, matching common real-world usage) rather than relying solely on automated tooling. It's genuinely revealing: interactions that look perfectly fine visually sometimes make no logical sense when experienced purely through screen reader announcement order and structure.
Keyboard navigation as a first-class test
Unplugging the mouse and navigating an entire flow using only the keyboard (tab, enter, arrow keys, escape) surfaces a different, equally important category of issue: focus getting trapped in a component, focus jumping somewhere unexpected after an action, or an interactive element that's simply unreachable by keyboard at all despite being clickable with a mouse.
Why bolted-on fixes tend to be fragile
Accessibility fixes applied after a component is fully built tend to patch the symptom (adding an ARIA label after the fact) without addressing the underlying structural issue, and they're more likely to break again the next time the component gets modified by someone unaware of the original fix's reasoning. Building accessible patterns into the base component library from the start means every screen built from those components inherits the correct behavior automatically.
The business case beyond compliance risk
Beyond the real legal exposure of inaccessible sites in many jurisdictions, accessible design overlaps heavily with genuinely better design for everyone: clear focus states help all keyboard users, good color contrast helps everyone in bright sunlight, clear heading structure helps anyone scanning a page quickly. Framing accessibility purely as risk mitigation undersells how much it actually improves the product for the whole audience.
Building an accessibility checklist into the design review, not just the QA phase
Catching accessibility issues at the design review stage, before a single line of code is written, is dramatically cheaper than catching the same issue during QA after a component is already built. We added a short, specific accessibility checklist to our design review process itself, does this design maintain sufficient contrast, is there a clear visual focus state, does information rely on color alone to communicate meaning, so that a meaningful share of issues get caught and corrected in the design file itself, before development ever starts, rather than being sent back for rework after the component has already been fully implemented once.
Catching accessibility issues at the design review stage, before a single line of code is written, is dramatically cheaper than catching the same issue during QA after a component is already built.
A real example of what a genuinely accessible fix looks like versus a bolted-on one
A client's custom dropdown component technically passed an automated accessibility scan, since it had the required ARIA attributes present. In an actual screen reader test, though, the announced state was confusing: opening the dropdown didn't clearly announce that it had opened, and selecting an option didn't clearly confirm the selection back to the user navigating by screen reader alone. The scanner had no way to catch this, since the attributes were technically present, just not producing a coherent experience in practice. Fixing it meant rebuilding the component's underlying interaction pattern, not just adjusting an attribute, which took real development time but produced a component that genuinely worked for screen reader users rather than one that merely satisfied an automated checklist while remaining confusing in actual use.
Involving people who actually use assistive technology, not just simulating it
The most valuable accessibility testing we do doesn't come from our own team simulating a screen reader user's experience, however carefully, it comes from involving people who actually rely on assistive technology in their daily lives, whether through a paid usability testing panel or an existing user base's own accessibility-focused feedback. A sighted team member turning off their monitor and using a screen reader for the first time picks up real, useful signal, but they lack the years of learned navigation patterns and expectations that an experienced daily screen reader user brings, and some genuinely important issues only surface with that deeper, lived familiarity. We recommend budgeting for at least one round of testing with actual assistive technology users on any project where accessibility is a serious priority, not just an internal simulation, since the gap between simulated and genuine expertise is real and worth closing before launch.
Documenting accessibility decisions so they survive team turnover
A recurring failure mode we see on client projects that inherited accessible components built by a since-departed team member: the accessible pattern works correctly, but nobody currently on the team understands why it was built that way, which means a well-intentioned future change can silently break the accessibility behavior without anyone realizing it. We document the specific reasoning behind non-obvious accessibility decisions directly in code comments and in the component library's own documentation, not just in a one-time design review note that gets forgotten, so a future developer modifying the component has the context needed to preserve its accessible behavior rather than accidentally undoing it while making an unrelated visual change.
Regression testing accessibility the same way we regression test anything else
A component that's genuinely accessible today can quietly stop being accessible after an unrelated future change, a new visual variant added without checking contrast, a refactor that drops a keyboard event handler, unless accessibility is checked as part of standard regression testing rather than treated as a one-time milestone. We add key accessibility checks to the same regression testing process that catches visual and functional regressions, since accessibility that isn't actively protected against regression tends to erode gradually and invisibly over a project's lifetime.