Skip to main content
HTML Validation

An element with the attribute “tabindex” should not appear as a descendant of an element with the attribute “role=X”.

About This HTML Issue

An element with a tabindex attribute is nested inside an element whose ARIA role, such as button, tab or checkbox, describes a single control that should take focus as one unit.

ARIA in HTML gives an element with one of these roles the same content rules as the native control it imitates. A <button> can hold text and other phrasing content, but no interactive elements and no elements with a tabindex attribute. A <div role="button"> follows the same rule.

The value of tabindex doesn't matter. With tabindex="0", the inner element becomes a second tab stop inside the control. With tabindex="-1", it stays out of the tab order, but a script or a mouse click can still focus it, so focus lands on part of the control instead of the control itself. Keyboard and screen reader users expect to reach the control once and activate it with Enter or Space. Most of these roles also have presentational children in WAI-ARIA, which means browsers shouldn't expose their descendants to assistive technologies as separate elements.

The validator checks descendants at any depth inside elements with role set to button, checkbox, img, link, math, menuitem, menuitemcheckbox, menuitemradio, option, progressbar, radio, separator, slider, switch or tab. The element with the role can have tabindex itself; the validator only flags its descendants.

It's a warning because the ARIA in HTML rule behind it is non-normative. Older validator builds reported it as an error, with "must not appear" in place of "should not appear". Inside a native <button> or <a>, a descendant with tabindex is still an error.

Remove tabindex from the descendant, and keep tabindex="0" on the element with the role. A native <button> is simpler, because it's focusable and responds to Enter and Space without extra attributes or scripts. Some carousel scripts give each slide role="button" and an inner tabindex="-1" element as a focus target. A slide with its own content, like an image and a caption, isn't a button, so remove role="button" from the slide and put a real <button> inside it for the action.

Invalid example

<div role="button" tabindex="0">
  <span class="label" tabindex="-1">Add to cart</span>
</div>

Valid example

<button type="button">
  <span class="label">Add to cart</span>
</button>

Valid example keeping the role

<div role="button" tabindex="0">
  <span class="label">Add to cart</span>
</div>

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?
🌍 Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
€5 / week

1K Weekly

1,000 monthly checks. Cancel anytime.

Get 1K Weekly →

Join teams across 40+ countries