Creating My Own Form
So we've established that you should use semantic HTML whenever possible. But what happens if you code something that for any reason looks a bit different? Let's take a look at at this specific criterion:
Name, Role, Value
For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.
In practice this means that if you create your own piece of code, you need to make sure important accessibility parts like aria roles and labels are present.
Example: My Cool Form
I want to add a small form on my site where a user can send in their name for a competition. Usually a form in React is structured something like this:
<div>Name Form</div><form onSubmit={handleSubmit}<div><label htmlFor="name">Name:</label><inputtype="text"id="name" name="name"value={formData.name}onChange={handleChange}required/></div><div><button type="submit">Submit</button></div></form>
Which looks something like this:
However, for this small form I want something tighter and just use a placeholder instead of the label:
<div>Name Form</div><form onSubmit={handleSubmit}<div><inputtype="text"placeholder="Name"id="name" name="name"value={formData.name}onChange={handleChange}required/></div><div><button type="submit">Submit</button></div></form>
This is my reworked form, note that there is no label next to the input.
At this point everything looks ok and I get no errors in my editor. However, since the label for the input is missing, a visitor using assistive technology will have trouble interacting with the form — and my site will be in violation of the WCAG 4.1.2 rule as stated above. Uh-oh!
So what's the solution? Since the <label>
is missing I don't get the accessibility automatically. After going over to MDN and reading about the issue, I see that a form MUST have a visible label of some sort.
Hm! Ok, I might have an idea.
I have a descriptive text at the top of my form, that could act as my visible label by adding aria-labelledby
to the <input>
element and a corresponding id
to the text.
<div id="nameform">Name Form</div><form onSubmit={handleSubmit}<div><inputtype="text"placeholder="Name"id="name" name="name"value={formData.name}onChange={handleChange}aria-labelledby="nameform"required/></div><div><button type="submit">Submit</button></div></form>
This works and fulfills the WCAG criterion, but is "Name Form" as clear and understandable as our original label of "Name"? No, probably not since the latter is the standard formulation. That's why it's ususally a good idea to stick to the establish method of <input>
and <label>
where possible.
A few final notes:
Textboxes like an <input>
can't use aria-label
on it's own beacause it's supposed to have a separate, visible <label>
element.
You should use a <label>
for each <input>
element. Another solution would've been to rework the <label>
from our first form and style it to look more like the title.
By using aria-labelledby
, several elements could reference the same id
.