# An element with the attribute “tabindex” must not appear as a descendant of the “button” element.

> Canonical HTML version: https://rocketvalidator.com/html-validation/an-element-with-the-attribute-tabindex-must-not-appear-as-a-descendant-of-the-button-element
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

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`

```html
<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

```html
<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`

```html
<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

```html
<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:

```html
<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.
