Label for inputs should be associated via wrapping, not "for" attribute
See original GitHub issueNot sure if this has been asked before (I wasn’t able to find an issue for it). HTML5 allows two ways to associate a label with an input field. The first one is via the “for” attribute and an id, like
<div>
<label for="myInput">My Input</label>
<input type="text" id="myInput" />
</div>
The other is to use the label as a wrapper, like
<label>
My Input
<input type="text" />
</label>
When using the first method if no id is set the browser does not know about the relation between the label and the input. This isn’t ideal for accessibility reasons. It’s also not ideal when using “Testing Library” with the getByLabelText
method to get the input - which simply won’t return the correct input as there is no obvious relation.
Current versions of material ui input components use the first method. I propose to switch to the label wrapping method. I see two major benefits from this:
- Using hierarchy alone, the browser knows which labels refer to which input, which improves accessibility.
- Given the first reason there is no reason to set Ids anymore. This is great because the dom tree should never contain the same id twice. Since react components are reusable this is not guaranteed when using the same component (one that has a TextField with an Id set) twice.
Possible disadvantages:
- dom diverges from material design (see: https://material.io/develop/web/components/input-controls/form-fields/). Interestingly Floating Labels in material design allow labels as wrapper (https://material.io/develop/web/components/input-controls/floating-label/, see “Avoid Dynamic ID Generation”)
- component styling could become more complex, at the very least it has to be adjusted
Issue Analytics
- State:
- Created 4 years ago
- Reactions:10
- Comments:16 (12 by maintainers)
Top GitHub Comments
Having dived more into how accessible names are computed I can only see a benefit with not having to provide ids which would be quite nice since it gives less opportunity to make mistakes.
If somebody wants to work on this I would suggest making this work for
– https://material-ui.com/components/text-fields/#components
Then we’ll see how we can incorporate this approach into TextField and how backwards compatibility looks.
Reakit supports wrapping inputs with the native
<label>
(not<FormLabel>
) just like one would do with HTML. The documentation uses this method specifically for checkboxes and radio buttons, but nothing prevents someone from using this for other input types.FormLabel
just exists so you can use the separate label approach without worrying about generating IDs. Reakit does this already.But, as you noted, this is all experimental right now and may change in the future.