What is a skip link in HTML, and why is tabindex="-1" often added to the element it targets?
answer
- bypass the repeated navigation block
- first focusable thing in the body
- main is not focusable by default
- negative so it is not a Tab stop
- must be perceivable when focused
basics
~20 sA skip link is an in-page link placed first in the tab order that jumps past repeated navigation to the main content. The target carries tabindex="-1" because elements like <main> are not focusable on their own.
solid answer
~50 sThe markup is an ordinary fragment link — `<a href="#main">Skip to main content</a>` — placed as the first focusable element in the body, pointing at `<main id="main" tabindex="-1">`. It exists for keyboard users who would otherwise tab through fifty navigation links on every page before reaching content. Following a fragment link scrolls the target into view and sets the point tabbing resumes from, but if the target is not focusable, focus itself does not move onto it reliably across browsers and screen-reader reading cursors may stay where they were. `tabindex="-1"` makes the target programmatically focusable so activating the link genuinely moves focus into the main content, while keeping it out of the Tab sequence so it never becomes a stray stop. The link must also be perceivable when focused — a skip link that stays invisible while focused is unusable for the sighted keyboard user it is meant to serve.
code
html · 9 lines<body>
<a class="skip-link" href="#main">Skip to main content</a>
<header>
<nav><a href="/products">Products</a> <a href="/pricing">Pricing</a></nav>
</header>
<main id="main" tabindex="-1">
<h1>Quarterly report</h1>
</main>
</body>go deeper
Know what a skip link is for, that it goes first in the body, and that its target needs tabindex="-1" because landmarks are not focusable by default.
Explain what following a fragment link does and does not do to focus, and why the negative tabindex rather than zero. Be able to write the markup from memory.
Show how you verify one in a real page with three keystrokes, name the failure modes you have actually seen ship, and place the requirement against WCAG 2.4.1 rather than treating it as a preference.
Own it at the template level: the skip link belongs in the shared layout with a stable target id, and your regression checks should fail when a redesign renames or removes that id.
## Why the link exists Every page repeats a header, a logo, and a navigation block. A mouse user's eye jumps straight past them; a keyboard user tabs through every one of those links on every page before reaching the content they came for. A skip link gives them a single Tab and Enter to bypass it. WCAG covers this under success criterion 2.4.1, Bypass Blocks, at level A — it is not an optional nicety. ## The markup ```html <body> <a class="skip-link" href="#main">Skip to main content</a> <header> <nav><!-- many links --></nav> </header> <main id="main" tabindex="-1"> <h1>Quarterly report</h1> </main> </body> ``` Two requirements sit in that snippet. The link is the first focusable element in the document, so one press of Tab from a fresh page load reaches it. And the target is a real element with a matching `id` — usually the `<main>` landmark, which is where content genuinely begins. ## Why the target needs tabindex="-1" Activating a fragment link makes the browser scroll the target into view and set the sequential focus navigation starting point there, so the next Tab continues from the target rather than from the link. What it does not reliably do, when the target is not itself focusable, is move focus onto the target. Behaviour has varied between browsers and assistive technologies, and a screen reader's reading cursor may stay in the header even though the viewport scrolled. `tabindex="-1"` closes the gap: the target becomes programmatically focusable, so following the link puts real focus on it. The negative value is deliberate — `tabindex="0"` would add `<main>` as a permanent Tab stop for everyone, which is noise. ## The link must be perceivable when focused A skip link is usually hidden until focused. The one implementation that never works is hiding it with `display: none` or `visibility: hidden`, because that removes it from the tab order entirely — it can never be focused, so it can never reveal itself. The working technique keeps it rendered and moves it out of view, bringing it back on focus; the exact styling is a CSS concern, but the markup consequence is the part to know: the element has to remain focusable at all times. It is also not a screen-reader-only feature. Screen-reader users have landmarks and heading navigation as alternatives; the sighted keyboard user has neither, and they are the person a visible-on-focus skip link serves. ## Variations worth knowing One skip link to `<main>` covers most pages. Some sites add a second to the search field, or a skip-past control for a long embedded widget such as a media player or a data table, where the block being bypassed is inside the content rather than before it. Each needs the same two pieces: a real fragment target and `tabindex="-1"` on it. ## The failures that ship The `href` points at an `id` that no longer exists after a redesign, so the link does nothing. The link sits after the navigation in DOM order and is therefore useless. It is implemented as `href="#"` plus a scroll handler, which moves the viewport but never focus, so tabbing resumes in the header. Or the target is a `<div>` wrapper rather than the landmark, so focus lands somewhere ambiguous. ## Testing it Load the page, press Tab once. The skip link should appear and be readable. Press Enter, then Tab again — the next focus stop must be inside the main content, not back at the top of the navigation. That three-key check catches nearly every broken implementation.
- Why does a skip link hidden with display: none never work?Content that is not rendered is not focusable, so Tab can never reach the link and it can never reveal itself. The working approach keeps the element rendered and positions it out of view, restoring it on focus — hiding it must be reversible by focus alone.
- Why tabindex="-1" on the target rather than tabindex="0"?`0` would put `<main>` into the tab order permanently, adding a meaningless stop for every user on every page. `-1` makes it focusable only when the link sends focus there, which is exactly the behaviour wanted and nothing more.
- Can the same tabindex="-1" target be reused elsewhere?Yes, and it usually is. A focusable `<main>` is the natural destination after a client-side view change too, so the same target serves both the skip link and post-navigation focus without any extra markup.
saying these in an interview costs you the question
- Says skip links are only for screen reader users
- Hides the skip link with display: none and expects it to work
- Uses href="#" with a scroll handler instead of a real fragment target
- Assumes <main> is focusable without tabindex
- Puts the skip link after the navigation in the DOM