Accessibility usually enters a project as a remediation exercise - an audit arrives, produces two hundred findings, and a team spends a quarter retrofitting. It is far cheaper built in, and the practices that achieve that are ordinary engineering discipline rather than specialist knowledge. Most issues trace back to a handful of habits.
01What automated testing cannot see
Automated tools reliably catch missing alternative text, insufficient colour contrast, missing form labels and invalid ARIA. That is genuinely useful and roughly a third of real issues. Run them in CI.
What they cannot evaluate is whether the alternative text is meaningful, whether focus order makes sense, whether a custom component behaves as its role implies, or whether an error message is actually announced. An image with alt="image" passes automated checks and helps nobody. These require human judgement, and no tool is close to replacing it.
- Run automated checks in CI as a floor, never as the standard.
- Test keyboard-only navigation on every new interactive component.
- Verify with a real screen reader, not a simulator.
- Include someone who uses assistive technology in real usability testing.
02Native elements first
The single highest-impact practice is using the correct HTML element. A button element is focusable, activates on both Enter and Space, announces its role, works with voice control, and honours user preferences - all without a line of JavaScript. A div with a click handler has none of that, and recreating it correctly takes considerably more code than most reimplementations contain.
The overwhelming majority of accessibility defects in modern applications come from reimplementing native controls. Before building a custom component, verify the native element genuinely cannot be styled to meet the design. It usually can, and styling constraints have relaxed substantially in recent years.
03Keyboard access is the fastest useful test
Put the mouse away and complete a core task using only the keyboard. This takes minutes and surfaces a large share of real problems: elements that cannot be reached, focus that vanishes into an invisible outline, modals that let focus escape behind them, and dropdowns that trap focus with no way out.
Focus management is where custom components most often fail. When a modal opens, focus must move into it, remain trapped while open, and return to the triggering element on close. When content is removed, focus must go somewhere sensible rather than reverting to the document body, which silently drops screen reader users back to the top of the page.
| Defect | Impact | Fix |
|---|---|---|
| div with click handler | Not keyboard reachable | Use a real button |
| Focus outline removed | Keyboard users lose position | Style it, never remove it |
| Modal without focus trap | Focus escapes behind the overlay | Trap focus; restore on close |
| Errors shown visually only | Not announced to screen readers | aria-live region, link to field |
| Placeholder as label | Disappears on input | Persistent label element |
| Icon-only button | No accessible name | aria-label or visually hidden text |
04Dynamic content must be announced
Single-page applications broke a lot of assistive technology behaviour that traditional page loads handled automatically. When content changes without a page load, screen readers are not notified unless you notify them explicitly.
Route changes should move focus to the new page heading and update the document title. Asynchronous status - form submission results, validation errors, loading completion - belongs in a live region so it is announced without stealing focus. Use polite announcements for informational updates and reserve assertive ones for genuine errors, because assertive interrupts whatever the user was reading.
05Make it structural
Accessibility knowledge concentrated in one enthusiastic engineer disappears when they change teams. The practices that persist are the ones embedded in the system: an accessible component library that makes the correct thing the default, linting that catches known-bad patterns at authoring time, and a review checklist item that is genuinely enforced.
The component library is the highest-leverage investment by a wide margin. If your button, modal, dropdown and form field components are correct once, every feature built from them inherits that correctness. Teams with a solid design system have dramatically fewer accessibility defects, not because engineers know more but because they are not making the decisions individually.
- Fix accessibility in shared components, where it scales.
- Add linting for known-bad patterns so feedback arrives at authoring time.
- Document the accessible usage of each component alongside its API.
- Test with assistive technology before release, not after an audit.
Topics
Priya Iyer
Staff Engineer · SyncTrix
Writes about the engineering decisions behind production systems - architecture, delivery and the trade-offs that only show up at scale.
Building something like this?
SyncTrix engineers AI, SaaS, platform and cloud systems for enterprises and high-growth teams. Tell us what you're shipping and we'll scope it with you.