HTML Guide
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.
Learn more:
Related W3C validator issues
A button element cannot contain a descendant element with the attribute tabindex.
A button element, or an element with the role=button attribute, is not allowed to be nested inside an <a> element.
An <a> element cannot contain a descendant element with the attribute tabindex.
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>
The tabindex attribute expects a valid integer value, not an empty string.
This attribute allows developers to make HTML elements focusable, allow or prevent them from being sequentially focusable (usually with the Tab key) and determine their relative ordering for sequential focus navigation.
This attribute accepts an integer value, where:
- A negative value means the element is not reachable via sequential keyboard navigation.
- A value of 0 means that the element should be focusable in sequential keyboard navigation, after any positive tabindex values. The focus navigation order of these elements is defined by their order in the document source.
- A positive value means the element should be focusable in sequential keyboard navigation, with its order defined by the value of the number. That is, tabindex="4" is focused before tabindex="5" and tabindex="0", but after tabindex="3".
In HTML, the <button> element is used to create interactive buttons. The W3C HTML Validator message suggests that your <button> element might be missing certain attributes that are typically expected for accessibility or functionality.
Understanding the Required Attributes
-
type Attribute:
-
The type attribute specifies the behavior of the button. It can take one of the following values:
- submit: Submits the form data to the server.
- reset: Resets the form data to its initial values.
- button: A generic button with no default behavior.
- If omitted, the default value is submit when the button is within a form.
<button type="button">Click me</button>
-
The type attribute specifies the behavior of the button. It can take one of the following values:
-
role and aria-checked Attributes:
- These attributes are related to ARIA (Accessible Rich Internet Applications) roles and states, which enhance accessibility by providing semantic meaning to assistive technologies.
- The role attribute defines the type of widget the button is supposed to represent, for example, role="switch" or role="checkbox".
- If using role="checkbox" or role="switch", the aria-checked attribute indicates whether the button is checked (true), unchecked (false), or if its state is indeterminate (mixed).
<!-- Example for a button acting as a checkbox --> <button type="button" role="checkbox" aria-checked="false">Toggle Option</button>
Recommendations
- Always define the type attribute to clearly specify the button’s intended behavior, especially within forms.
- If the button acts like a toggle control such as a checkbox or switch, include the appropriate role and use aria-checked to reflect its current state.
- Ensure alignment of ARIA attributes with the intended behavior and visual representation of the button for users, both with and without assistive technologies.
A <button> tag can’t include other <button> tags inside. Most probable cause is an unclosed <button> tag, like in this example:
<button>Submit
<button>Cancel</button>
The button role is used to make an element appear as a button control to a screen reader and can be applied to otherwise non-interactive elements like <div>. If you’re already using a <button> element, then it’s redundant to apply it the role button, as that’s implicit.
<!-- Instead of this -->
<button role="button">Buy</button>
<!-- Do this -->
<button>Buy</button>