Detailed explanation
An accessible React component should expose its purpose, name, state, and interactions to people using keyboards, screen readers, or other assistive technology. Start with semantic HTML: use a button for an action, an anchor with href for navigation, and appropriate headings and landmarks for structure. Native elements provide browser behaviour and accessibility information that a clickable div does not. React does not change these requirements; JSX ultimately produces DOM elements, which browsers use to build an accessibility tree for assistive technology.
Every form control needs an accessible name, usually through a visible label. In JSX, connect label htmlFor to the input id; use React’s useId when reusable component instances need unique identifiers. The example’s Email label correctly names the email input, while type="email" and required provide native input semantics and validation constraints. A placeholder is not a substitute for a label because it disappears while typing and may be difficult to perceive. Associate instructions and error messages using aria-describedby, and mark an invalid field with aria-invalid when validation identifies an error. Explain errors in text rather than only changing the border colour.
All interactions must work with a keyboard, with a logical focus order and a clearly visible focus indicator. Prefer native keyboard behaviour rather than recreating it with event handlers, and avoid positive tabIndex values. Manage focus deliberately when the interface changes: a modal dialog should receive focus, contain keyboard focus while open, and normally return focus to its trigger when closed. Do not move focus unnecessarily during ordinary rerenders. Keep text readable with sufficient contrast, and communicate selected, loading, or error states through text or other cues as well as colour.
Use ARIA to supply information that native HTML cannot express, not to replace correct semantics. The example’s button should expose aria-expanded={open}; aria-controls can identify its associated panel. If it opens ordinary navigation, do not automatically apply role="menu", which implies specialised keyboard behaviour. Dynamic status messages may need a polite live region. Interviewers look for practical reasoning: explain how you would check keyboard navigation, accessible names, focus behaviour, and screen-reader output, alongside automated accessibility checks.
Key points to remember
- Prefer semantic HTML and native controls over custom clickable elements.
- Give every form control an accessible name and connect help or error text appropriately.
- Support keyboard interaction, logical focus order, visible focus, and deliberate focus restoration.
- Add ARIA only where needed, and keep exposed states consistent with the interface.
- Use sufficient contrast and non-colour state cues; combine automated checks with manual testing.
Common mistakes candidates make
- Using clickable divs or spans without native button semantics and keyboard behaviour.
- Treating placeholders as labels or reusing the same input id across component instances.
- Assuming ARIA attributes implement interactions or that passing automated checks guarantees accessibility.
Likely follow-up questions
What does aria-expanded do, and does it implement a menu?
It tells assistive technology whether the content controlled by an element is expanded or collapsed. It does not show content, move focus, or implement keyboard navigation; your component must provide the appropriate behaviour.
How would you manage focus in a React modal?
Use a correctly implemented native dialog or an accessible dialog primitive, moving focus inside when it opens and preventing interaction with background content. Support appropriate dismissal, normally including Escape, and restore focus to the trigger when the dialog closes.
How would you test a component for accessibility?
Test keyboard-only operation, visible focus, accessible names, and any required arrow-key interactions. Run automated checks such as axe, then manually check screen-reader announcements and dynamic state changes because automation cannot verify every interaction.
Interview tip: Structure your answer around semantics, labels, keyboard access, focus, and state communication, then illustrate them with the email input and expandable button.
