About This HTML Issue
The HTML specification defines button as an interactive content element that accepts phrasing content as its children, but explicitly forbids interactive content as descendants. When you add a tabindex attribute to an element, you make it focusable and potentially interactive, which violates this content model restriction.
This rule exists for important reasons. A button element is a single interactive control — when a user presses Tab, the entire button receives focus as one unit. If elements inside the button also have tabindex, screen readers and keyboard users encounter nested focusable items within what should be a single action target. This creates confusing, unpredictable behavior: users may tab into the button’s internals without understanding the context, and assistive technologies may announce the inner elements separately, breaking the expected interaction pattern.
Browsers may also handle nested focusable elements inconsistently. Some may ignore the inner tabindex, while others may allow focus on the nested element but not properly trigger the button’s click handler, leading to broken functionality.
How to fix it
The most straightforward fix is to remove the tabindex attribute from any elements inside the button. If the inner element was given tabindex="0" to make it focusable, it doesn’t need it — the button itself is already focusable. If it was given tabindex="-1" to programmatically manage focus, reconsider whether that focus management is necessary within a button context.
If you genuinely need multiple interactive elements in the same area, restructure your markup so that the interactive elements are siblings rather than nested inside a button.
Examples
❌ Incorrect: span with tabindex inside a button
<button type="button">
<span tabindex="0">Click me</span>
</button>
The span has tabindex="0", making it a focusable descendant of the button. This violates the content model.
✅ Correct: Remove tabindex from the descendant
<button type="button">
<span>Click me</span>
</button>
The span no longer has tabindex, so the button behaves as a single focusable control.
❌ Incorrect: Multiple focusable elements inside a button
<button type="button">
<span tabindex="0" class="icon">★</span>
<span tabindex="-1" class="label">Favorite</span>
</button>
Both inner span elements have tabindex attributes, which is invalid regardless of the tabindex value.
✅ Correct: Style inner elements without making them focusable
<button type="button">
<span class="icon">★</span>
<span class="label">Favorite</span>
</button>
✅ Correct: Restructure if separate interactions are needed
If you need an icon and a separate action side by side, use sibling elements instead of nesting:
<span class="icon" aria-hidden="true">★</span>
<button type="button">Favorite</button>
This keeps the button as a clean, single interactive element while placing the decorative icon outside of it.
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.