( Operable / WCAG 2.4.3 )

Element has a positive tabindex

ModerateLevel AWCAG 2.4.3 — Focus Order

What is this issue?

An HTML element has a tabindex attribute set to an integer of 1 or higher. Any positive value creates a priority tab sequence entirely separate from the page’s normal DOM order: the browser visits every positive-tabindex element first, in ascending numeric order, before moving on to the rest of the page’s elements in their regular document order.

This is the specific, root-cause version of a broader family of tab-order defects. Where other pages in this cluster describe the symptom (a confusing sequence, detected by scanning or by a human walkthrough), this rule targets the single most common cause directly: the mere presence of a positive integer in a tabindex attribute, which is unambiguous to detect and almost always worth removing on sight.

Why does this matter?

A positive tabindex doesn’t just reorder two elements once; it creates an ongoing maintenance liability. Every element added to the page later, anywhere, either has to be given its own carefully chosen positive value to fit into the intended sequence, or falls back to DOM order and gets visited only after every positive-value element on the page, regardless of where it sits visually. In practice, nobody maintains this discipline consistently as a codebase grows, and the sequence quietly drifts out of sync with the visual layout over time.

The failure mode compounds specifically because it’s invisible until someone actually tabs through the page: a developer adding a new field to a form has no reason to think about tabindex numbering elsewhere on the page, so the newly-added field silently lands in the wrong spot in the tab sequence the moment it ships, with nothing in a routine code review likely to catch it.

Who is affected?

  • Keyboard users: experience a tab sequence that jumps to a handful of numbered elements first, then falls back to a separate DOM-order pass for everything else, producing a jarring, hard-to-predict sequence that gets worse every time the page changes.
  • Screen reader users: build a mental model of a page’s structure partly from the order things are announced in; a positive-tabindex-driven sequence disrupts that model in the same way it disrupts a sighted keyboard user’s visual tracking, since screen reader users commonly navigate by Tab as well as by other commands.

What users experience

Ben uses NVDA and keyboard-only navigation due to a repetitive strain injury. On a job application form, a developer set tabindex="1" through tabindex="5" on the five fields visible in the original design, intending to guarantee their order. Months later, a “Preferred start date” field was added between fields two and three without a matching tabindex value, so it falls back to DOM order and lands dead last in the sequence, after the five originally numbered fields, including the submit button. Ben tabs from field two straight to field three, then field four, five, and the submit button, submitting the form before he ever reaches the start-date field NVDA never announced as coming next.

How do I fix it?

Remove the positive tabindex value entirely. This works because it restores the browser’s default behavior of following DOM order, which requires no manual numbering scheme and stays automatically correct every time the page’s structure changes, since the tab sequence is derived directly from source order rather than a separate value someone has to remember to update.

If elements currently rely on their tabindex values to appear in a specific sequence that doesn’t match their DOM position, reorder the elements in the HTML source itself to match the intended sequence instead. This achieves the same outcome the positive tabindex values were trying to force, but durably: the visual layout, the DOM order, and the tab order all stay linked from that point forward with no numbering scheme left to maintain.

Code Examples

Before
<button tabindex="3">Submit</button>
<input tabindex="1" type="text" name="email">
<input tabindex="2" type="text" name="name">
After
<input type="text" name="name">
<input type="text" name="email">
<button>Submit</button>

Removing every tabindex value and putting the elements in the DOM in their intended order achieves the identical tab sequence the numbered values were aiming for, but without a numbering scheme that has to be manually maintained: any future field inserted into this block automatically lands in the correct tab position based on where it sits in the markup.

Common Mistakes

Mistake: “Numbering tabindex values explicitly guarantees the order I want, which feels safer than relying on DOM order.” It guarantees the order at the moment it’s written, but that guarantee doesn’t extend to the future: every element added later needs a correctly chosen number too, and nothing enforces that automatically. DOM order provides the same guarantee with none of that ongoing burden, since it’s derived from the markup itself rather than a parallel numbering system.

Mistake: “tabindex=‘0’ and a positive tabindex are basically the same feature, just with different numbers.” They behave completely differently. tabindex="0" inserts an element into the natural DOM-order sequence at its actual document position, exactly the right tool for making a custom element focusable. Any positive value instead removes the element from that natural sequence and places it into a separate, prioritized one, which is a fundamentally different behavior, not a stronger version of the same one.

Mistake: “It’s fine as long as all the tabindex values on the page are unique.” Uniqueness prevents ties between elements but does nothing about the deeper problem: any element without a positive tabindex value, which, on a growing page, is inevitably most of them over time, gets pushed after all the numbered ones regardless of its visual position, producing exactly the scrambled sequence this rule exists to catch.

How RedFlag Detects This

Custom automated: RedFlag’s own DOM detector, runs on every scan. RedFlag scans every element with a tabindex attribute present on the page and flags any whose value parses to a positive integer, checking the raw attribute value directly rather than relying on any layout or rendering signal.

False negative: none typical for this specific, narrow condition; presence of a positive tabindex value is a binary, unambiguous fact the detector reads directly from the DOM. False positive: none typical either, since a positive tabindex value is essentially never the correct choice in modern web development regardless of surrounding context, unlike checks that require judging intent or content quality. Manual step: confirm removing the value (or reordering the DOM) doesn’t unintentionally change which element receives initial or programmatic focus elsewhere in the page’s JavaScript, since some code may reference elements by their expected tab position.

Manual Testing

  1. Open the page’s HTML source or DevTools’ Elements panel and search for tabindex="1", tabindex="2", or any other positive value.
  2. For each match, note its position in the DOM relative to its visual position on the page.
  3. Tab through the page and confirm whether the numbered elements are visited first, out of their visual order, before the rest of the page’s elements.
  4. Remove each positive value (or reorder the DOM to match the intended sequence) and Tab through the page again to confirm the sequence now follows the visual layout.

2.4.3 Focus Order: Components must receive focus in an order that preserves meaning and operability. A positive tabindex is one of the clearest and most common concrete violations of this criterion, since it deliberately overrides the order that would otherwise preserve visual meaning.

Tab order doesn’t match visual order is the broader, symptom-level automated check this rule’s root cause almost always triggers alongside it; a positive tabindex is the single most common reason that page fires.

Manual check flagged an incorrect tab order is the human-confirmed version of the same broader symptom, catching sequence problems (including from this cause) that only become obvious during a real keyboard walkthrough.

Element in the focus order has no matching interactive role is a related but distinct focus-order defect: a Tab stop with no explanatory role, rather than one landing in the wrong position in the sequence.

Modal opens without moving focus into it and Modal is missing focus management cover a different focus-order failure family in the same 2.4.3 criterion, specific to dialog open/close behavior rather than static element ordering.

References

Frequently asked questions

Is tabindex="0" also a problem?

No. tabindex="0" adds an element to the natural DOM-order tab sequence, which is exactly the correct way to make a custom element like a div-based button keyboard-focusable. Only positive values (1, 2, 3, and so on) are the problem this rule documents, because they create a separate priority sequence instead of joining the natural one.

What's the difference between this rule and Tab order doesn't match visual order?

This rule is the specific, narrow cause: any element with a tabindex value above zero, detected directly by scanning for the attribute. Tab order does not match visual order is the broader symptom-level check for a scrambled sequence from any cause, including this one and others like CSS order. A positive tabindex will almost always trigger both.

Is there ever a legitimate reason to use a positive tabindex?

Essentially no, in modern web development. It was occasionally used decades ago to work around browser inconsistencies in DOM-order tab handling that no longer exist in any current browser. Today it only ever creates a maintenance burden: a separate sequence that has to be manually kept in sync with every future layout change, with no offsetting benefit.

Does removing a positive tabindex ever change visual appearance?

No. tabindex has no effect on layout, size, color, or any other visual property; it only affects the DOM's built-in keyboard-focus behavior. Removing a positive value is a purely behavioral change, safe to make without any visual regression testing beyond confirming the fix itself.