The keyboard:skip-link rule flags a page whose first Tab stop is not a working link to the main content. Keyboard users then tab through the logo, the whole menu and the search on every page before they reach anything new. The fix is a "Skip to content" link as the first focusable element, pointing at an element that exists.
What the rule means
WCAG 2.4.1 requires a mechanism to bypass blocks of content that repeat on every page. Strictly, landmarks and headings are recognised ways to meet it – but they only help people whose software can jump by landmark or heading, which is mainly screen reader users. For a sighted person using the keyboard, a skip link is the mechanism: one Tab, one Enter, and they are past the navigation.
A skip link may be hidden until it takes focus. It has to become visible then, and its target has to exist.
Who is affected
Sighted keyboard users – people with motor disabilities using a keyboard, switch or mouth stick, and people with low vision using a magnifier. A site navigation of thirty links means thirty Tab presses on every page, and with a switch every press is slow and tiring.
Why the check fails
- No skip link at all – the first Tab lands on the logo.
- A skip link that is not first, behind a cookie banner, a language switcher or a "call us" link.
- A broken target:
href="#main"while the content hasid="content", or no id at all. href="#"or a script-driven button instead of a same-page link.- Themes and templates that shipped a skip link and a later redesign removed.
How to fix it
Make the skip link the first element in <body>, point it at the main content and give that element the id.
<!-- Before: the first Tab lands on the logo -->
<body>
<header>
<a href="/"><img src="/logo.svg" alt="Example Ltd – home"></a>
<nav aria-label="Main menu">
<a href="/products/">Products</a> <a href="/contact/">Contact</a>
</nav>
</header>
<main><h1>Our products</h1></main>
</body>
<!-- After: a skip link first, pointing at an element that exists -->
<body>
<a class="skip-link" href="#content">Skip to content</a>
<header>
<a href="/"><img src="/logo.svg" alt="Example Ltd – home"></a>
<nav aria-label="Main menu">
<a href="/products/">Products</a> <a href="/contact/">Contact</a>
</nav>
</header>
<main id="content"><h1>Our products</h1></main>
</body>
Hide it until it is needed, and bring it into view on focus:
.skip-link { position: absolute; left: -9999px; }
.skip-link:focus { left: 1rem; top: 1rem; padding: .5rem 1rem; background: #ffffff; color: #1a1a1a; }
How to test it manually
- Load the page, click into the address bar and press Tab once. Does a "Skip to content" link appear?
- Press Enter. Does the page move to the main content, and does the next Tab continue from there?
- Check the link is the first Tab stop on every template – home, category, article, checkout.
- Check it stays visible while it has focus, also at mobile width.
Related WCAG criterion
2.4.1 Bypass Blocks, Level A. Related: 2.4.3 Focus Order and 1.3.1 Info and Relationships, where landmarks and headings give screen reader users their own way past the navigation.
How Reviseberg reports it
This rule comes from Reviseberg's keyboard agent, not from axe-core. Before pressing any key, the agent looks at the first focusable element on the page. It passes if that element is a link to #something and an element with that id exists; otherwise the page fails with "The page offers no way to skip the repeated navigation", and the first step of the keystroke trail says why – no link at all, or a link to a target that does not exist.
That is all it checks. It does not test whether the target is the main content, whether the link becomes visible on focus (the next Tab step shows that, reported as undefined), or whether landmarks already serve screen reader users. That is why the finding is reported at the lowest severity. If you decide your page meets 2.4.1 another way, record the decision on the finding with your reason.