HTML Guide for button
A button element, or an element with the role=button attribute, is not allowed to be nested inside an <a> element.
A button 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>
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>
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.
An a element is not allowed to be nested inside a <button> element, or an element with the role=button attribute.
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 button element, or an element with the role=button attribute, is not allowed to be nested inside an <a> element.
An element with role=button can’t have an input element as descendant.
The ARIA role button can be added to an element to make it behave like a <button> – just like a <button> is not allowed to contain other <input> elements as descendants, any element with this role is not allowed to contain them either.
All these examples in the following code will raise a similar issue:
<div role="button">
<input type="checkbox" />
</div>
<button>
<input type="checkbox" />
</button>
<a>
<input type="checkbox" />
</a>
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.