React · Frontend system thinking
How do you build accessible React interfaces?
Short answer
Start with semantic HTML, label every control, support keyboard and focus behaviour, and use ARIA only to fill gaps. Then test with a keyboard, a screen reader and automated checks.
React does not make an interface accessible by itself. The browser's built-in elements already provide roles, keyboard behaviour and focus semantics. A <button> handles Enter and Space; a clickable <div> does not. Use the native element first and add ARIA only when no native element expresses the pattern.
function SignupForm({ onSubmit }) {
const [error, setError] = useState("");
return (
<form onSubmit={onSubmit}>
<label htmlFor="email">Email address</label>
<input
id="email"
name="email"
type="email"
aria-invalid={Boolean(error)}
aria-describedby={error ? "email-error" : undefined}
/>
{error && (
<p id="email-error" role="alert">
{error}
</p>
)}
<button type="submit">Create account</button>
</form>
);
}The essentials
- Use headings, lists, buttons, links and form elements for their intended purpose
- Associate every input with a visible label using
htmlForandid - Make all actions reachable and operable with a keyboard
- Manage focus when opening dialogs, changing routes or revealing content
- Do not remove focus outlines without providing an equally visible replacement
- Meet colour-contrast requirements and do not rely on colour alone
For dynamic content, use a live region such as role="status" for polite updates and role="alert" for urgent errors. For a modal, trap focus while it is open, close on Escape, label it with aria-labelledby, and restore focus to the trigger when it closes.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1When should you use ARIA instead of native HTML?
- 2How do you manage focus when a modal opens and closes?
- 3What is the difference between role=status and role=alert?
- 4Why is a clickable div worse than a button?
Say it in the interview
I start with semantic HTML, because native elements already provide roles, keyboard behaviour and focus. I label every input, keep focus visible, support keyboard navigation and manage focus for dialogs and route changes. I add ARIA only where native semantics are not enough, and I test with a keyboard, a screen reader and automated checks. Accessibility is part of the component design, not a final cleanup pass.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live React mock interview and get scored feedback on depth, clarity and confidence.