Accessible React Forms: Labels, Focus, and Errors
Accessible React forms need real labels, keyboard focus, and error announcements, not just ARIA. Screen reader users must perceive inputs and validation without visual cues. The common footgun is placeholder text or divs instead of label elements with htmlFor.
WHY IT EXISTS: Forms are the primary way users create accounts, submit payments, and edit data. For users who navigate with keyboards or screen readers, a form is only usable if the browser can map each input to its purpose, its current state, and its errors through the accessibility tree. React's component model makes it easy to abstract inputs into reusable pieces, but that abstraction often strips away the label associations and focus management that native HTML provides for free. Accessible React forms exist to restore that semantic contract without sacrificing component reuse.
THE MENTAL MODEL: Think of an accessible form as a conversation between the user and the browser's accessibility tree. Every input must introduce itself with a name, announce when something is wrong, and guide the user to the next step via focus. In React, this means props are not just for styling and state; they are the wiring that connects visual elements to the non-visual tree. If a screen reader cannot derive meaning from the DOM alone, the form is broken regardless of how clean the state logic looks.
HOW IT WORKS: Associate every input with a label using htmlFor and id, or by wrapping the input in a label. Manage focus explicitly with useRef and focus so that validation errors move the cursor to the first failing field. Announce errors with aria-live regions or role alert so screen readers speak them without requiring visual attention. Keep focus indicators visible and do not override outline none without a replacement. Use fieldset and legend for grouped controls like radio buttons. In controlled components, ensure the value prop does not destroy the native semantics.
WHEN TO USE IT: Use these patterns for every production form that collects user data, especially authentication, checkout, search, and settings panels. They are also critical in modal dialogs where focus trapping and return focus are required. Any form that runs validation on submit or blur should announce errors programmatically.
WHEN NOT TO USE IT: Do not add aria-live announcements to every keystroke in a high-frequency input like a live search or game controller, because the chatter will overwhelm screen reader users. Avoid over-engineering a single static newsletter email input with complex focus management if native HTML validation and a simple label suffice.
ONE CANONICAL EXAMPLE: A login form with email and password fields. Each input has a label with htmlFor pointing to the input id. On failed submit, an error message appears in a div with aria-live polite and the password input receives focus via a ref. The submit button is never disabled while the form is invalid; instead, it remains clickable and triggers the error announcement, because disabled buttons are not focusable and their state is invisible to screen readers.
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.