Fix Tabindex Values Greater Than Zero for Better Accessibility

Learn how to fix tabindex values greater than zero in Lighthouse accessibility audits
Harlan WiltonHarlan Wilton4 min read Published

Positive tabindex values create unpredictable keyboard navigation that frustrates screen reader users and breaks the natural flow of your page.

What's Happening

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.

Diagnose

  1. Open DevTools (F12 or Cmd+Shift+I)
  2. Run this in the Console to find offending elements:
document.querySelectorAll('[tabindex]').forEach((el) => {
  if (Number.parseInt(el.getAttribute('tabindex')) > 0) {
    console.log(el, 'tabindex:', el.getAttribute('tabindex'))
  }
})
  1. Use Tab to navigate the page and notice where focus jumps unexpectedly

Fix

1. Remove Positive Tabindex Values

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>

2. Reorder Your DOM Instead

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.

Framework Examples

In Vue/Nuxt, audit your components for hardcoded tabindex values:
<template>
  <!-- Avoid this -->
  <button :tabindex="priority">
    Click me
  </button>

  <!-- Prefer this -->
  <button>Click me</button>
</template>
If using dynamic tabindex for focus management, stick to 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} />

Verify the Fix

  1. Run Lighthouse again and confirm the tabindex audit passes
  2. Tab through your page from start to finish
  3. Verify focus moves in a logical, predictable order matching visual layout

Common Mistakes

  • Using tabindex to "prioritize" important elements — This breaks navigation for everyone. Important elements should be early in the DOM, not given high tabindex.
  • Setting tabindex="1" thinking it means "focusable" — Use tabindex="0" to add an element to the natural tab order. tabindex="1" forces it to receive focus before everything else.
  • Third-party libraries injecting positive tabindex — Check modal dialogs, tooltips, and date pickers. Override or configure them to use tabindex="0" or -1.
  • Confusing tabindex="-1" with positive values — Negative tabindex is fine. It removes elements from tab order while allowing programmatic focus, which is useful for modals and skip links.

Tabindex issues often appear alongside:

Test Your Entire Site

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.