This article takes a look at the <label> element, including which elements need labeling, explicit vs implicit labeling, and more.
Which form elements need a <label>?
The <label> element is used to provide a visible text label and accessible name for some specific HTML elements such as:
<button><input>(except fortype="hidden")<meter><output><progress><select><textarea>
Note: While the <label> is the preferred mechanism for naming form controls, accessible names can also be provided via other mechanisms such as aria-label or aria-labelledby when appropriate.
Which form elements do not typically use a <label>?
Many form-based elements don't require a <label>. In some of these cases, adding a <label> would either be invalid or confusing for assistive technologies.
For the <input> elements with a type of button, reset and submit, a label can be provided by the contents of the value attribute.
<input type="button" value="Login">
<input type="reset" value="Reset form">
<input type="submit" value="Submit">
For the <input> element with a type of image, a label can be provided by the contents of the alt attribute.
<input type="image" src="ball.png" alt="Ball">
For the <input> element with a type of hidden, there should be no associated <label> as this form control is never presented to the user.
<input type="hidden">
While it is allowed, the <button> does not require a <label> as its content be used instead.
<button>Content</button>
The <fieldset> must not have an associated <label>, as the contents of the <legend> provides its name.
<fieldset>
<legend>Content</legend>
</fieldset>
The <legend> must not have an associated <label>, as it is used to provide a caption for the content of its parent <fieldset> element.
<fieldset>
<legend>Content</legend>
</fieldset>
The <option> must not have an associated <label>, as its contents are used instead.
<label for="aaa">Choose a dinosaur:</label>
<select id="aaa">
<option>Tyrannosaurus</option>
<option>Velociraptor</option>
</select>
The <optgroup> must not have an associated <label>, as the contents of the label attribute are used instead.
<label for="aaa">Choose a dinosaur:</label>
<select id="aaa">
<optgroup label="Theropods">
<option>Tyrannosaurus</option>
<option>Velociraptor</option>
</optgroup>
</select>
The <datalist> is not a labelable element in HTML.
<label for="aaa">Choose a flavor:</label>
<input id="aaa" list="bbb">
<datalist id="bbb">
<option value="Chocolate">
<option value="Mint">
</datalist>
Explicit or implicit (wrapped)?
If a <label> is associated with any of these form controls, it should be explicitly associated via matching for and id values:
<label for="aaa">Name</label>
<input id="aaa" type="text">
The form control can be implicitly associated if it is wrapped inside its <label>:
<label>
Name
<input type="text">
</label>
Note: Implicitly associated labels are not reliably supported by voice control software.
To solve this, you can place form controls inside the label and also make them explicitly associated via matching for and id values:
<label for="aaa">
Name
<input id="aaa" type="text">
</label>
Label order (best practice)
HTML does not require a specific ordering of <label> elements relative to their associated form controls.
A label may appear before or after the control, and both patterns are valid.
However, user testing has shown that label order can significantly affect comprehension and usability for some people.
In particular, placing the visible label text before the form control can reduce confusion for:
- people with cognitive disabilities
- people using screen magnification
- people with reduced peripheral vision
When the control appears before its label, users may encounter an interactive element before they understand its purpose, especially when only a portion of the screen is visible at high zoom levels.
Based on this evidence, many teams choose patterns that prioritise understanding before interaction.
In the case of radio buttons and checkboxes, the opposite is true. The visible labels are best placed after radio and checkbox form controls.
Which elements are allowed as descendants of the <label> element?
The <label> element only allows specific types of Phrasing content:
- no descendant
<label>elements. - no descendant labelable elements (unless it is the element's labeled control).
So, no flow elements are allowed as descendants of the <label>:
<label>
<div></div>
</label>
<label>
<p></p>
</label>
And a <label> is not allowed as a descendant of the <label>:
<label>
<label></label>
</label>
Labelable elements, such as the <button>, <input>, <meter>, <output>, <progress>, <select> and <textarea> are allowed as descendants - but only if they are the element's labeled control.
So, adding a single instance of any of these elements inside the <label> is allowed.
<label>
<input>
</label>
But the <label> cannot contain more than one of these elements, as they would not be the element's labeled control:
<label>
<input>
<input>
</label>
And that's it for the <label> element today!