DEV Community

FrozonFreak
FrozonFreak

Posted on Originally published at thewebhig.hashnode.dev

Add a skip link (Web HIG tip #11)

Load your site, click the address bar, and press Tab. Count how many presses it takes to reach the first thing in the main content. Every one of those stops is a logo, a nav link, or a menu toggle that a keyboard user has to step through on every page, every time.

Web HIG tip #11 (Quick #74): Provide a "Skip to main content" link as the first tabbable element.

Why it matters

A skip link is the keyboard user's shortcut past the header:

  • Sighted keyboard and switch users have no standard browser shortcut to jump past navigation, so without a skip link they tab through it on every page load
  • Screen reader users can already jump by landmarks and headings, but a skip link still gives them a fast, predictable first stop
  • Long mega-menus, search bars, and account links make the walk longer on exactly the sites where people visit the most pages
  • A skip link that is hidden with display: none, or that points at an id that doesn't exist, looks fine in a review and does nothing for anyone

The full HIG lists skip links in §5.3, Keyboard Focus & Interaction. On the WCAG side, this builds on 2.4.1 Bypass Blocks (Level A). WCAG also accepts landmarks or headings as a way to meet 2.4.1; the HIG asks for the link specifically. Quick #74 is Quick-only guidance, with no separate rule ID, and it pairs with Quick #25: one <main> landmark per page, which is the natural target.

The rule of thumb

Ask: from a fresh page load, does the first Tab offer a way straight to the content?

Put the link first in <body>, point it at <main>, and hide it only until it receives focus.

<body>
  <a class="skip-link" href="#main">Skip to main content</a>
  <header>…</header>
  <main id="main" tabindex="-1">…</main>
</body>
Enter fullscreen mode Exit fullscreen mode
/* Off-screen until focused, still in the tab order */
.skip-link {
  position: absolute;
  inset-inline-start: 1rem;
  top: -10rem;
  z-index: 100;
}

.skip-link:focus {
  top: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

Modern browsers already continue the next Tab from the target. tabindex="-1" makes <main> actually take focus, without adding it to the tab order, so screen readers announce the jump and the behavior is consistent across browsers.

Don't hide the link with display: none or visibility: hidden. Both remove it from the tab order, so the link can never be reached. A link that stays invisible while focused also fails 2.4.7 Focus Visible (AA): the user is on something they can't see.

Do this instead

  • Make the skip link the first focusable element, ahead of cookie banners, announcement bars, and the logo
  • Point it at the id on <main>, and check that the id exists on every template, not just the home page
  • Reveal it on focus, in front of any sticky header, with the same visible focus ring as the rest of the site
  • Write the link text in the page's language, and keep it plain: "Skip to main content"
  • In single-page apps, check that your router doesn't treat #main as a route change and swallow the jump (hash-mode routers are the usual culprit). If it does, handle the click and focus <main> yourself

Quick check for your app

Open a page on example.com, click the address bar, and press Tab once. The skip link should appear where you can see it. Press Enter, then Tab again: focus should land on the first link or control inside the main content, not back in the header. Repeat on a deep page, a form, and a search results page. A tool can find a missing link or a broken href, but only tabbing through tells you whether the jump actually works.


The Web HIG is an open set of guidelines for how the web should behave, not a component library. Design systems define how it looks. The Web HIG defines how it behaves.

Top comments (0)