Skip links, focus & tabindex
Semantic layout is only half the story. Keyboard users also need a predictable
focus order so they can reach the main content quickly. That’s where skip
links and tabindex come in.
Skip link pattern
A skip link is a simple anchor placed right at the top of the page, before your
header and navigation:
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<header>...</header>
<main id="main-content">
...
</main>
On this tutorial page, try pressing Tab from the very top: the first
thing you land on is the “Skip to main content” link that jumps you straight into
the tutorial.
Three useful tabindex values
-
No
tabindex at all – default behaviour.
Interactive elements like links, buttons, and form fields are focusable in the
natural order. Structural elements like <div> and
<main> are not focusable.
-
tabindex="0" – makes an element focusable and places
it in the normal tab order, alongside links and buttons.
-
tabindex="-1" – makes an element focusable
programmatically (for example via a skip link or script), but it is
skipped when users press Tab.
In practice, you rarely need anything else. A good mental model:
0 = “Put me in the queue.”
-1 = “Don’t put me in the queue, but let me be
called to the front when needed.”
Why this page uses tabindex="-1" on <main>
Some browsers will only move focus to a non-interactive element if it is explicitly
focusable. By adding tabindex="-1" to <main>, we
make it a reliable focus target for the skip link and any scripts that call
.focus(), without adding an extra Tab stop for keyboard users.
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<main id="main-content" tabindex="-1">
...
</main>
This pattern is also useful for:
- Error summaries at the top of a form (“There were 3 problems…”).
- Dialog and modal containers when they open.
- Any landmark or section you want to jump to and announce via screen readers.