HTML Guide
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>
Learn more:
Related W3C validator issues
A button element, or an element with the role=button attribute, is not allowed to be nested inside an <a> element.
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>
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.
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>
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 an <input> element whose type is submit, then it’s redundant to apply it the role button, as that’s implicit.
<!-- Instead of this -->
<input type="submit" role="button">Buy</button>
<!-- Do this -->
<input type="submit">Buy</button>
The <summary> HTML element specifies a clickable summary, caption, or legend for a <details> element’s disclosure box. As the <summary> element has an implicit button role, it’s not needed to include it explicitly.
Here’s an example, clicking the <summary> element toggles the state of the parent <details> element open and closed.
<details>
<summary>I have keys but no doors. I have space but no room. You can enter but can’t leave. What am I?</summary>
A keyboard.
</details>
When you encounter the issue where the <a> element is nested inside an element with role="button", it’s important to understand that this can lead to accessibility conflicts. The role="button" indicates that the element is interactive, similar to a button. Nesting an <a> (which is also an interactive element) inside it can confuse assistive technologies.
How to Fix This Issue
You should either change the structure so that the <a> is not inside the button or change the role of the button to avoid this violation. Here are two common approaches to resolve the issue:
Option 1: Remove the <a> Tag
Replace the <a> tag with an appropriate action directly inside the element with role="button".
Example Before:
<div role="button">
<a href="#link">Click here</a>
</div>
Example After:
<div role="button" tabindex="0" onclick="location.href='#link';">
Click here
</div>
Here, we use JavaScript to navigate to the link when the div is clicked.
Option 2: Remove the role="button"
If the <a> tag is sufficient by itself, you can remove the role="button" from the surrounding element.
Example Before:
<div role="button">
<a href="#link">Click here</a>
</div>
Example After:
<a href="#link">Click here</a>
This maintains the desired navigation without creating a conflict between the button and link semantics.
A button element is not allowed to contain other button elements, or other elements with role=button.
The button role identifies an element as a button to assistive technology such as screen readers. A button is a widget used to perform actions such as submitting a form, opening a dialog, canceling an action, or performing a command such as inserting a new record or displaying information. Adding role="button" tells assistive technology that the element is a button but provides no button functionality
A <li> element is used to define an item of a list, so adding the listitem role to it is redundant.
The ARIA listitem role can be used to identify an item inside a list of items. It is normally used in conjunction with the list role, which is used to identify a list container.
<section role="list">
<div role="listitem">List item 1</div>
<div role="listitem">List item 2</div>
<div role="listitem">List item 3</div>
</section>
When possible, you should use the appropriate semantic HTML elements to mark up a list and its list items — <ul> or <ol>, and <li>. For example:
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
There can only be one visible <main> element in a document. If more are needed (for example for switching between them with JavaScript), only one can be visible, the others should be hidden toggling the hidden attribute.
Example of 2 main elements, where only one is visible:
<main>
<h1>Active main element</h1>
<!-- content -->
</main>
<main hidden>
<h1>Hidden main element</h1>
<!-- content -->
</main>