Back to Accessibility
Accessibility
medium
mid

What are the key accessibility practices every frontend engineer should know?

Use semantic HTML first (`button`, `label`, `nav`); reach for ARIA only when no semantic element fits. Ensure keyboard operability, visible focus, sufficient contrast, and screen-reader-friendly names. Test with VoiceOver/NVDA and a keyboard.

7 min read·~15 min to think through

Three layers of accessibility, in priority order:

1. Semantic HTML. Use the right element. <button> is keyboard-operable, focusable, and announces as "button" to a screen reader for free. <div onClick> requires re-implementing all of that and almost always misses something.

2. ARIA — only as needed. ARIA describes widgets that HTML can't (combobox, tabs, dialog). The first rule of ARIA is: don't use ARIA. The second is: if you must, follow the WAI-ARIA Authoring Practices patterns exactly. A wrong role is worse than none.

3. Keyboard + focus. Every interactive element must be reachable with Tab and operable with Enter/Space (and Esc / arrows where appropriate). Visible focus indicators are required (don't outline: none without an alternative). Manage focus on route change and modal open/close.

Other essentials:

  • Labels. Every input has a <label> (clickable target) or aria-label.
  • Color contrast. ≥ 4.5:1 for body text, 3:1 for large text and UI.
  • Don't rely on color alone — pair status with icons / text.
  • alt on every image; empty alt="" for decorative.
  • Live regions (aria-live="polite") for async updates so screen readers announce them.

Test with: a keyboard only, VoiceOver / NVDA, axe-core (CI), Lighthouse. Lived experience on assistive tech beats any audit tool.

Code

tsx
// ❌ Broken — not focusable, no keyboard, not announced
<div onClick={save}>Save</div>

// ✅ Right
<button type="button" onClick={save}>Save</button>
Don't reinvent a button
tsx
<div role="status" aria-live="polite">
  {isSaving ? "Saving..." : saved ? "Saved" : null}
</div>
Live region for async status

Follow-up questions

  • What are the WCAG conformance levels (A, AA, AAA)?
  • How do you correctly trap focus inside a modal?
  • How do you announce a route change to a screen reader in an SPA?

Common mistakes

  • Using `<div role='button'>` without keyboard handlers.
  • Hiding focus styles globally with `outline: none`.
  • Putting text inside `<img alt>` that duplicates surrounding text.

Performance considerations

  • Accessibility has near-zero perf cost. Focus management and live regions are cheap.

Edge cases

  • Toast announcements: too many `aria-live` updates flood screen readers; throttle.
  • Skip-link to main content is essential for keyboard users on long pages.

Real-world examples

  • GOV.UK Design System and Adobe Spectrum publish accessible components with full keyboard + screen-reader behavior — copy patterns, don't reinvent.

Senior engineer discussion

Senior signal: discuss accessibility as a first-class engineering concern (a11y in CI, design-system primitives like Radix UI/HeadlessUI), focus management strategies, internationalization (RTL, lang), and the legal/business case (ADA, EAA).