Skip to main content
Accessibility AccessLint 0.16

Skip links must point to a valid target on the page.

About this AccessLint rule

A skip link is a navigation aid that lets users jump past repeated content, such as a site's main navigation menu, and land directly on the primary content of the page. When a skip link's href attribute points to an id that does not exist on the page, the link does nothing. The user clicks it, and nothing happens.

This affects keyboard users and screen reader users most directly. Sighted mouse users can scroll past navigation without thinking about it, but a keyboard user must press Tab through every single link in a navigation bar before reaching the main content. On a site with dozens of navigation links, this is tedious and slow. A working skip link removes that burden by moving focus to the main content area in a single keypress.

Screen reader users face the same problem. They hear every navigation item announced as they move through the page. A skip link that actually works lets them bypass all of that and get straight to the content they came for.

This rule maps to WCAG 2.4.1 Bypass Blocks (Level A). That success criterion requires that a mechanism exists for bypassing blocks of content that are repeated across multiple pages. A skip link is the most common way to satisfy this requirement, but it only works if the link target is valid. A broken skip link fails the criterion because the bypass mechanism is non-functional.

How to fix it

  1. Make sure the skip link's href value (e.g., #main) matches the id attribute of an element on the page.
  2. The target element should be the container for the page's main content, or the <main> element itself.
  3. Place the skip link as the first focusable element in the page's DOM order, before any navigation or header links.
  4. The skip link can be visually hidden by default and revealed when it receives focus, using CSS. This keeps it out of the visual layout for sighted mouse users while remaining available to keyboard users.
  5. On the target element, add tabindex="-1" if it is not natively focusable (like a <div> or <main> element). Some browsers do not move focus to non-focusable elements even when the fragment identifier matches, so tabindex="-1" ensures consistent behavior.

Examples

Skip link with a missing target

The link points to #main-content, but no element on the page has that id. Activating the link does nothing.

<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
<main>
<h1>Welcome</h1>
<p>Page content goes here.</p>
</main>
</body>

Skip link with a valid target

The href="#main-content" matches the id="main-content" on the <main> element. The tabindex="-1" attribute makes the target programmatically focusable.

<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
<main id="main-content" tabindex="-1">
<h1>Welcome</h1>
<p>Page content goes here.</p>
</main>
</body>

CSS to visually hide the skip link until focused

This approach keeps the skip link off screen until a keyboard user tabs to it. When focused, it appears at the top of the page.

.skip-link {
position: absolute;
left: -9999px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
.skip-link:focus {
position: fixed;
top: 0;
left: 0;
width: auto;
height: auto;
padding: 8px 16px;
background: #000;
color: #fff;
z-index: 1000;
}

Common mistakes

A few patterns cause this rule to trigger:

  • The href has a typo, such as href="#maincontent" when the element's id is main-content.
  • The target element exists in a template or component that has not yet rendered when the skip link is evaluated.
  • The id attribute was removed during a refactor but the skip link still references it.
  • The skip link uses href="#" or href="", which does not point to any specific element.

The fix is always the same: make sure the href fragment matches an actual id on the page, and confirm that the target element is present in the DOM when the page loads.

Detect accessibility issues automatically

Rocket Validator scans your site with complementary accessibility engines, helping teams find issues across every page.

Help us improve our guides

Was this guide helpful?
๐ŸŒ Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
$7 / 7 days

Pro Trial

Full Pro access. Cancel anytime.

Start Pro Trial โ†’

Join teams across 40+ countries