Positive tabindex values create unpredictable keyboard navigation that frustrates screen reader users and breaks the natural flow of your page.
Elements have tabindex values greater than 0, which forces them into an explicit navigation order. While technically valid HTML, this overrides the natural DOM order and creates a confusing experience. Users tab to high-tabindex elements first, then jump back to tabindex="0" elements, making navigation feel random and broken.
document.querySelectorAll('[tabindex]').forEach((el) => {
if (Number.parseInt(el.getAttribute('tabindex')) > 0) {
console.log(el, 'tabindex:', el.getAttribute('tabindex'))
}
})
Replace any positive tabindex with 0 or remove it entirely:
<!-- Before -->
<button tabindex="5">Submit</button>
<input tabindex="1" type="text">
<a tabindex="3" href="/about">About</a>
<!-- After -->
<button>Submit</button>
<input type="text">
<a href="/about">About</a>
If elements need a different tab order, change their position in the HTML:
<!-- Before: Using tabindex to force order -->
<div>
<button tabindex="2">Second</button>
<button tabindex="1">First</button>
</div>
<!-- After: Correct DOM order, no tabindex needed -->
<div>
<button>First</button>
<button>Second</button>
</div>
Use CSS (flexbox order, grid placement, or absolute positioning) to achieve visual order while keeping logical DOM order.
<template>
<!-- Avoid this -->
<button :tabindex="priority">
Click me
</button>
<!-- Prefer this -->
<button>Click me</button>
</template>
0, -1, or remove entirely.For React, search your codebase for tabIndex props:
// Avoid
<input tabIndex={2} />
// Prefer
<input />
// or for programmatic focus management
<input tabIndex={0} />
tabindex="0" to add an element to the natural tab order. tabindex="1" forces it to receive focus before everything else.tabindex="0" or -1.Tabindex issues often appear alongside:
Tabindex issues often hide in shared components that appear across dozens of pages. Unlighthouse runs Lighthouse on every page of your site, catching accessibility problems wherever they appear so you can trace issues back to the source component.