HTML Guide
A label
element is not allowed as a descendant of a button
element.
The label
element represents a caption in a user interface. The caption can be associated with a specific form control, known as the label element’s labeled control, either using the for
attribute, or by putting the form control inside the label element itself.
Learn more:
Related W3C validator issues
The label element may only contain one labelable descendant.
For example:
<label for="age">
Age
<select id="age">
<option>young</option>
<option>old</option>
</select>
</label>
The label element may contain only one labelable descendant.
For example:
<label for="age">
Age
<select id="age">
<option>young</option>
<option>old</option>
</select>
</label>
A button element, or an element with the role=button attribute, is not allowed to be nested inside an <a> element.
A descendant element with a tabindex attribute cannot be nested inside an element that uses role="button".
The role="button" attribute marks an element as a button for assistive technologies, but true button elements (using the button tag) should typically manage focus and tab order on their own. Adding a nested element with tabindex inside a role=”button” container can confuse keyboard navigation and accessibility tools. Each tabbable element should have a clear, non-overlapping place in the focus order.
Incorrect example (causes the error):
<div role="button">
<span tabindex="0">Click me</span>
</div>
Corrected example 1: Move tabindex to the container
<div role="button" tabindex="0">
<span>Click me</span>
</div>
Corrected example 2: Use a native button element
<button>
<span>Click me</span>
</button>
Whenever possible, use native elements like button, as they provide correct focus, keyboard, and accessibility behavior without extra attributes or roles. Only use role="button" with proper keyboard and accessibility support if absolutely necessary, and avoid tabbable descendants within such containers.
A button element cannot contain a descendant element with the attribute tabindex.
When nesting an input element inside a label that has a for attribute, the id attribute of the input is required to match it.
The label element represents a caption in a user interface. The caption can be associated with a specific form control, known as the label element’s labeled control, either using the for attribute, or by putting the form control inside the label element itself.
When the input is inside the label, there’s no need to specify a for attribute as there can only be one input, as in this example:
<label>
Age
<input type="text" name="age">
</label>
However, if the for attribute is specified, then it must match the id of the input like this:
<label for="user_age">
Age
<input type="text" name="age" id="user_age">
</label>
When nesting a select element inside a label that has a for attribute, the id attribute of the select is required to match it.
The label element represents a caption in a user interface. The caption can be associated with a specific form control, known as the label element’s labeled control, either using the for attribute, or by putting the form control inside the label element itself.
When the select is inside the label, there’s no need to specify a for attribute as there can only be one select, as in this example:
<label>
Age
<select>
<option>young</option>
<option>old</option>
</select>
</label>
However, if the for attribute is specified, then it must match the id of the select like this:
<label for="age">
Age
<select id="age">
<option>young</option>
<option>old</option>
</select>
</label>
The aria-expanded attribute can only be true, false, or undefined.
This attribute indicates whether a grouping element is expanded or collapsed.
An element like <h1>, <h2>, etc., used to define a heading, does not accept the button role.
The following HTML code is invalid because the <h2> element can’t have role="button"
<h2 role="button">Some heading</h2>
Instead, you can nest the <h2> inside a <div> with that role. In this case however, browsers automatically apply role presentation to all descendant elements of any button element as it is a role that does not support semantic children.
<div role="button">
<h2>Some heading</h2>
</div>
A <li> element, used to define a list item, does not accept the button role.
This HTML code is invalid because the <li> elements can’t have role="button":
<ul>
<li role="button">One</li>
<li role="button">Two</li>
</ul>