Several times this year, I’ve answered variations of the following question:
Is it strictly necessary for form fields and labels to have
for/id
association, or is it enough to wrap the<label>
around the<input>
The answer is — Wrapping is enough in theory, but isn’t quite in practice.
What’s the difference?
All form fields must have an associated label, so that screen reader users know which field the label is referring to, and so that voice control users can speak the label text to focus the field (e.g., Click email address
for a field labeled “Email address”). The association also provides a pointer shortcut, making it possible to focus the field by clicking the label.
Wrapping the label around the field is known as implicit association, and it’s a very common pattern:
<label>
Email address
<input type="email">
</label>
This pattern is often cited as a usability benefit, since it makes the whole area clickable, rather than the label and field being separate targets, which can be particularly helpful if they’re not directly next to each other.
However if the label and field are separate elements, then they must be associated using for
and id
attributes, which is known as explicit association:
<label for="email">Email address</label>
<input id="email" type="email">
So what’s the problem?
All browsers and assistive technologies support explicit association, however implicit association is not reliably supported by voice control software.
Both Dragon Naturally Speaking for Windows, and Voice Control for macOS and iOS, don’t recognize implicit association, so the Click email address
command wouldn’t work.
This is not a blocker, because users have multiple ways to reach and activate controls. For example, Voice Control users can say Show numbers
to show an overlay of numbers next to every interactive element, and then say the relevant number to use that control.
But the problem is easily fixable anyway, simply by adding explicit association:
<label for="email">
Email address
<input id="email" type="email">
</label>
Conclusion
Wrapping the <label>
around the <input>
is fine, and is sufficient for conformance on its own, however adding explicit association with for
and id
is still necessary in practice.
Resources
- Browsing with speech recognition (TetraLogical)
- Creating Accessible Forms: Accessible Form Controls (WebAIM)
- Understanding SC 2.5.3: Label in Name (WCAG)
Image credit: Alpha.
Comments
Thank you for bringing attention to this important topic on a11y of form elements.
How about if you just add an `id`-attribute to the `input`-element – and still wrap the `label` around without a `for`-attribute?
“`html
Email address
“`
Might this actually solve the problem and enable ‘voice control’ to correctly pilot to the form element – as the form element can then be directly accessed by `id`?
All examples:
https://codepen.io/rr-it/pen/zYVMVap
Just another test case:
`input-field with labeling provided via `aria-label`. Can an input field like this be properly accessed by ‘voice control’?
https://codepen.io/rr-it/pen/QWXJeLp
On macOS 14.6.1 I manage to access the field with “Click email address” command with Voice Control with this code :
Email address
Maybe it’s now fixed ?
Fields can also have description and errors. If all of that is inside a label, it’s all considered the input label which can be super verbose.
For that reason, I prefer keeping them in separated html nodes and use id and aria-* attributes to connect them.
What’s your thoughts on that? Thanks!
Sorry for the delay in responding to these.
Ayke Halder — using `id` without `for` doesn’t create an association, so no, that doesn’t work. Using `aria-label` does work, but that’s not helpful without a visible label, because the voice control user doesn’t know what the text is. That can work with things like graphical buttons, if the icon’s command text is obvious, like “Save” for a disk icon button.
Myrdin Mogan — I’ve read in a couple of places that the issue might be fixed in recent Voice Control updates, including iOS 18, so I’ll investigate and update the article as applicable.
Sandrina Pereira — I agree that additional descriptions shouldn’t be inside the label, because it’s too verbose, and semantically smelly. That was the standard technique before ARIA, but not anymore. However these approaches aren’t mutually exclusive, you can have the input inside the label, with a separate description element after the label. Personally, I prefer to have the input and label separate anyway, with each pair grouped by `<div>` (so they gracefully degrade to blocks, whereas labels are inline by default), and I space the label using padding rather than margin, so there’s no dead space in between them.
n.b., you can do reverse association, with `id` on the label and `aria-labelledby` on the input, which does create a semantic association for assistive technology users, but it doesn’t provide the pointer shortcut for clicking the label to focus the field (although that can be easily scripted).