THN Interview Prep

Accessibility semantics & keyboard

Accessibility is not an audit badge. It is the guarantee that a user can perceive the state, operate the controls, understand the result, and keep using the product with their tools. Senior frontend work makes that guarantee part of component contracts and release criteria.

Core details

AreaContractCommon bug
SemanticsNative elements or correct role/name/stateClickable div invisible to keyboard and AT
KeyboardEvery action reachable and understandable without pointerHover-only menus and trapped focus
FocusFocus moves predictably and restores after overlaysModal closes and focus jumps to <body>
NameControls expose an accessible nameIcon-only buttons with no label
StatusAsync changes announced when needed“Saved” toast never reaches screen reader
MotionReduced-motion variant preserves meaningDisabling animation also hides state change

Treat WCAG 2.2 as acceptance criteria for user journeys: perceivable, operable, understandable, and robust, with testable success criteria at A/AA/AAA levels.

Prefer native controls: button for actions, a href for navigation, label + input associations for forms. Custom widgets owe a full implementation: role, state, keyboard map, focus behavior, pointer behavior, and assistive technology testing.

Accessible names: derive from visible text, aria-label, aria-labelledby, or associated labels. The name should match visible intent so speech users can operate the same control they see.

Dialogs: move focus into the dialog, trap focus while open, make background inert, close with Escape unless product policy forbids it, and restore focus to the invoking control.

Live regions: use aria-live="polite" for non-urgent async status and assertive sparingly for critical interruption. Do not announce every keystroke or repeated loading tick.

Understanding

Assistive technologies consume the semantic tree, not pixels. Roles/names regressions silently delete functionality for screen-reader and voice-control users—even if screenshots look unchanged. Keyboard navigation surfaces affordances accidentally coupled to hover or fine-pointer precision assumptions.

Keyboard navigation surfaces assumptions that pointers hide—broken focus traps or missing names block entire tasks.

Focus management is part of your API contract, not polish after mock approval.

Good accessibility is usually simpler engineering: use platform controls, preserve document structure, keep state deterministic, and test the task with keyboard only. Most costly bugs come from custom components pretending to be native without implementing native behavior.

Practical examples

<button type="button" aria-expanded={open} aria-controls="filters-panel">
  Filters
</button>

<section id="filters-panel" hidden={!open}>
  ...
</section>

This creates a clear relationship between the button and controlled region. The state must stay synchronized; stale aria-expanded is a user-facing bug.

<button type="button" aria-label="Delete invoice">
  <TrashIcon aria-hidden="true" />
</button>

The icon is decorative; the button owns the name.

Testing path

  • Run automated rules to catch missing names, invalid roles, contrast issues, and landmark mistakes.
  • Perform keyboard-only walkthroughs for top journeys.
  • Test at least one screen reader/browser pairing for complex widgets.
  • Include focus assertions in component tests for dialogs, comboboxes, menus, and route transitions.
  • Review reduced-motion and zoom behavior, especially at 200% and narrow widths.

Senior understanding

ProbeStrong answer cues
“Is a11y a checkbox?”continuous CI linting plus scripted keyboard rehearsal paths
“Who owns regressions?”design system + QA matrix + telemetry on focus traps
“Motion marketing conflict?”document trade + reduced-motion variant—not silent degradation
“Why native controls?”platform semantics, keyboard behavior, form integration, and AT support come for free

Use automated audits (axe-class scans) as a baseline, not the whole story—they rarely catch nuanced focus regressions alone; complement with scripted keyboard walkthroughs.

Failure modes

  • Adding role="button" without Enter/Space behavior and focus styling.
  • Removing focus outlines globally.
  • Using aria-hidden="true" on a parent of focusable content.
  • Rendering validation errors visually but not associating them with fields.
  • Opening a modal without making the rest of the page inert.

Interview drill

Question: "Design an accessible modal or combobox. What must be true?"

Model answer structure:

  1. Start with the native pattern if one exists; otherwise define role, name, state, and keyboard map.
  2. Manage focus deliberately: initial focus, tab containment where appropriate, Escape behavior, and focus restore.
  3. Keep visual, keyboard, pointer, and assistive-technology states synchronized.
  4. Announce async status or validation errors through associated text or live regions.
  5. Test with automated scans, keyboard-only walkthroughs, and at least one screen-reader/browser pairing for complex widgets.

Follow-ups to expect:

  • "Why is aria-hidden dangerous around focusable content?"
  • "What does automated accessibility testing miss?"
  • "How do route transitions affect focus?"

Diagram

Loading diagram…

See also

Mark this page when you finish learning it.

Spotted something unclear or wrong on this page?

On this page