Skip to content
Back to Design Hub

Skip Link & Bypass Blocks

A 'Skip to main content' link as the first focusable element, for keyboard users to bypass nav.

AccessibilityBeginner

Why

Keyboard users Tab through every nav link on every page load — 15 tabs to reach content. A skip link jumps them straight to main, the single highest-impact a11y feature for keyboard users (WCAG 2.4.1).

When

Every page with repeated nav before main content. It's the first element in the DOM, before the header. No exceptions for marketing pages either.

How

1. Markup — <a href="#main" class="skip-link">Skip to main content</a> as the first body element 2. Visually hidden — clip/sr-only until :focus, then show as a top-left banner 3. Target — <main id="main" tabindex="-1">; tabindex=-1 lets it receive programmatic focus 4. Focus on click — the browser scrolls to #main but doesn't always focus it; add a focus handler 5. Test — Tab on page load, the skip link appears first, Enter jumps to main, next Tab is in content 6. Multiple — skip to nav, skip to footer for complex pages; one skip-to-main covers 95% of cases 7. Label — 'Skip to main content' is the convention; don't get creative, users recognize the phrase

Example

/* Skip link — hidden until focused */ .skip-link { position: absolute; top: 0; left: 0; transform: translateY(-100%); /* off-screen */ background: var(--color-action-primary); color: white; padding: 0.5rem 1rem; z-index: var(--z-toast); transition: transform 150ms; } .skip-link:focus { transform: translateY(0); } /* slides in on focus */ <!-- index.html --> <body> <a href="#main" class="skip-link">Skip to main content</a> <header><!-- 15 nav links --></header> <main id="main" tabindex="-1"> <h1>Page content</h1> </main> </body> // Ensure focus moves to main (some browsers only scroll) document.querySelector(".skip-link")?.addEventListener("click", (e) => { e.preventDefault(); document.getElementById("main")?.focus(); });

Common Problems

  • ⚠Skip link only visually hidden with display:none — never focusable, defeats the purpose
  • ⚠main has no tabindex=-1 — browser scrolls but doesn't focus, screen reader stays on the link
  • ⚠Skip link after the header in DOM — keyboard users Tab through nav before reaching it

Best Practices

  • ✓First element in <body> — before the header, so it's the first Tab stop on every page
  • ✓Use sr-only + :focus to reveal, never display:none — must be focusable when off-screen
  • ✓Add tabindex=-1 to <main> — ensures focus (not just scroll) moves there on click

FAQ