Accessible Forms
Labeling
Every HTML form control, such as <input>
and <textarea>
, needs to be labeled accessibly. We need to provide descriptive labels that are also exposed to screen readers.
The following resources show us how to do this:
- The W3C shows us how to label elements
- WebAIM shows us how to label elements
- The Paciello Group explains accessible names
Although these standard HTML practices can be directly used in React, note that the for
attribute is written as htmlFor
in JSX.
INFO
Typically, you will place every <input>
inside a <label>
tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input. If you can’t nest <input>
into a <label>
, associate them by passing the same ID to <input id>
and <label htmlFor>
. To avoid conflicts between multiple instances of one component, generate such an ID with useId
.
import { useId } from "react";
export default function Form() {
const ageInputId = useId();
return (
<>
<label>
Your first name:
<input name="firstName" />
</label>
<hr />
<label htmlFor={ageInputId}>Your age:</label>
<input id={ageInputId} name="age" type="number" />
</>
);
}
Notifying the user of errors
Error situations need to be understood by all users. The following link shows us how to expose error texts to screen readers as well: