ESC

Type to search the knowledge base.

Skip Links

Add skip links so keyboard users bypass repetitive nav — placement, focus styles, target main, and SPA considerations.

beginner3 min read
  • accessibility
  • skip-links

Keyboard and screen reader users should not have to Tab through a mega-nav on every page. A skip link is the first focusable control: “Skip to main content.” It jumps focus to the primary content landmark.

Docs: WCAG 2.4.1 Bypass Blocks, WebAIM skip navigation.

Minimal implementation

<body>
  <a class="skip-link" href="#main">Skip to main content</a>
  <header>…nav…</header>
  <main id="main" tabindex="-1">
    <h1>Dashboard</h1>
    …
  </main>
</body>

tabindex="-1" lets the main target receive programmatic focus without adding an extra Tab stop permanently.

Visually hidden until focused

.skip-link {
  position: absolute;
  left: 0.5rem;
  top: 0.5rem;
  transform: translateY(-150%);
  z-index: 10000;
  padding: 0.5rem 1rem;
  background: #000;
  color: #fff;
}

.skip-link:focus {
  transform: none;
  outline: 2px solid #fff;
  outline-offset: 2px;
}

Don’t display: none in a way that removes it from focus order. Off-screen / clip patterns that remain focusable are standard.

Multiple skips

Large apps may offer:

  • Skip to main
  • Skip to search
  • Skip to footer

Keep the list short. Label clearly.

<a class="skip-link" href="#main">Skip to main content</a>
<a class="skip-link" href="#search">Skip to search</a>

SPA routing

After client navigation, ensure:

  1. id="main" still exists.
  2. Optionally move focus to main on route change (in addition to skip).
  3. Title updates — language and page titles.
// on route change
const main = document.getElementById('main');
main?.focus();

Common failures

  1. href="#main" but no matching id.
  2. Target not focusable — focus stays on skip link visually confusing.
  3. Skip link not first in DOM/tab order.
  4. Invisible focus styles on the link.
  5. Smooth scroll only without moving focus.

Interview out-loud answer

“Skip links are the first focusable element, jump to main with href and a focusable target, and become visible on focus. They satisfy bypass blocks for repetitive nav. SPAs must keep the target and manage focus on route changes.”

2.4.1 Bypass Blocks is the success criterion. Skip links are the classic technique; consistent navigation and landmarks also help. Landmarks alone are not enough for keyboard users who Tab linearly — they still walk the whole header unless a skip exists or they use SR shortcuts.

Multiple landmarks, one skip

If the page has nav, search, and side filters, a single skip to main is usually enough. Adding five skip links creates its own navigation tax. Prefer one primary skip to main, solid landmarks with labels, and a second skip only for huge secondary chrome.

.skip-link:not(:focus):not(:focus-visible) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Verify Tab still lands on it first after styling.

  1. Load page, press Tab once — skip link focused and visible.
  2. Activate (Enter) — focus moves to #main, not just scroll.
  3. Next Tab enters main content controls.
  4. Repeat after client-side route changes.

Production checklist

Confirm first-in-tab-order, visible on focus, target id exists, target can take focus, and SPA navigations still work.

Further reading

Related guides