About This Accessibility Rule
The tabindex attribute controls whether and in what order an element receives keyboard focus. When set to a positive integer (e.g., tabindex="1", tabindex="5", or even tabindex="100"), the browser tabs to that element before any elements without a tabindex or with tabindex="0". This means the tab order no longer follows the natural reading order of the page, which is the order elements appear in the DOM.
Why This Is a Problem
Keyboard-only users, screen reader users, and people with motor disabilities rely on a logical, predictable tab order to navigate a page. A positive tabindex breaks that predictability in several ways:
- Unexpected tab order: The user is pulled to elements out of their visual and logical sequence, causing confusion and disorientation.
-
Elements appear to be skipped: Because positive-
tabindexelements are visited first, when the user later reaches their position in the document, the browser skips them since they were already visited. Users may not realize they need to cycle through the entire page to reach those elements again. -
Cascading maintenance problems: If you set
tabindex="1"on one element, you must then set explicittabindexvalues on every focusable element between it and wherever you want tab order to resume — potentially dozens or hundreds of elements. This is fragile and nearly impossible to maintain.
Even a single element with tabindex="100" will be tabbed to first on the page, regardless of how many focusable elements exist. The number doesn’t represent a position among 100 items; it simply means “before everything with a lower or no tabindex.”
This rule is classified as a Deque Best Practice and addresses usability for people who are blind, deafblind, or have mobility disabilities. While not mapped to a specific WCAG success criterion, it directly supports the principles behind WCAG 2.4.3 Focus Order (Level A), which requires that the navigation order of focusable components be meaningful and operable.
How to Fix It
There are three approaches, depending on your situation:
1. Change tabindex to 0
Setting tabindex="0" places the element in the natural tab order based on its position in the DOM. This is the simplest fix, though you should verify that the resulting order still makes sense.
2. Remove tabindex and restructure the HTML
Native interactive elements like links (<a>), buttons (<button>), and form controls (<input>, <select>, <textarea>) are already in the tab order by default. If you find yourself needing a positive tabindex to “fix” the order, the real solution is usually to rearrange the elements in the source code so the DOM order matches the intended navigation sequence.
Keep in mind that certain CSS properties can make the visual order differ from the DOM order, leading to confusing tab behavior:
-
position: absoluteandposition: relative -
float: leftandfloat: right -
orderin Flexbox or Grid layouts
Always ensure that DOM order = visual order = tab order.
3. Use tabindex="-1" with JavaScript
Setting tabindex="-1" removes the element from the tab order entirely but still allows it to receive focus programmatically via JavaScript (e.g., element.focus()). This is useful for complex interactive widgets where you need to manage focus dynamically, such as within tab panels, menus, or modal dialogs.
Examples
Incorrect: Positive tabindex values
<a href="/home" tabindex="3">Home</a>
<a href="/about" tabindex="1">About</a>
<a href="/contact" tabindex="2">Contact</a>
<a href="/blog">Blog</a>
In this example, the tab order would be: About → Contact → Home → Blog. This does not match the visual order, which is confusing for keyboard users.
Correct: Natural tab order with no tabindex
<a href="/about">About</a>
<a href="/contact">Contact</a>
<a href="/home">Home</a>
<a href="/blog">Blog</a>
Here, the HTML source order matches the desired tab order. No tabindex is needed.
Correct: Using tabindex="0" for non-interactive elements
<div role="button" tabindex="0" aria-label="Toggle menu">
☰
</div>
Using tabindex="0" places this custom button in the natural tab order without disrupting the sequence of other focusable elements.
Correct: Using tabindex="-1" for programmatic focus
<div role="tabpanel" id="panel-1" tabindex="-1">
<p>Panel content goes here.</p>
</div>
<script>
// Focus the panel when its corresponding tab is activated
document.getElementById('panel-1').focus();
</script>
The panel is not reachable via the Tab key during normal navigation, but JavaScript can move focus to it when appropriate — such as when a user activates a tab control.
Help us improve our guides
Detect accessibility issues automatically
Rocket Validator scans thousands of pages with Axe Core and the W3C Validator, finding accessibility issues across your entire site.