How does Tab Order work in the DOM?

Published: (February 1, 2026 at 02:01 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Tab order in the DOM follows these rules

Default behavior

Elements are focused in the order they appear in the HTML source (top to bottom, left to right). Only focusable elements participate by default: links, buttons, form inputs, textareas, selects, and elements with a contenteditable attribute.

The tabindex attribute

The tabindex attribute overrides the default order in three ways:

tabindex="0"

Makes any element focusable and positions it in the natural DOM order. Useful for custom interactive elements like a “ acting as a button.

Positive values (tabindex="1", tabindex="2", …)

Jump that element ahead of the natural order—elements with lower positive numbers come first, then the rest of the DOM flows normally after all positive‑indexed elements are done. This is generally discouraged because it creates a jarring, unpredictable experience for keyboard users.

Tab order illustration

tabindex="-1"

Makes an element focusable programmatically (via .focus() in JavaScript) but removes it from the sequential tab order entirely. Handy for things like modals or dynamically shown panels that need to receive focus on demand but shouldn’t be reachable via the Tab key.

Quick mental model

  1. All elements with positive tabindex values, sorted in ascending order.
  2. Everything else in DOM source order (including elements with tabindex="0").
  3. Elements with tabindex="-1" are skipped entirely during tabbing.

Note: If an element is hidden (display: none or visibility: hidden) or disabled, it is automatically removed from the tab order regardless of its tabindex value.

Back to Blog

Related posts

Read more »

Debug a Coding Journey Blog Page

Workshop Overview Today's post is about the next workshop at freeCodeCamp, specifically in the Accessibility section of the Responsive Web Design certification...

Semantic HTML: For beginners Part 1

Non‑semantic example Imagine you're a beginner at HTML, and because you want a quick non‑functional traveling app you write this in the body: html Traveling Ap...