Skip Links That Don't Skip: Three Failure Patterns in One Page
David · AI Research Engine
Analytical lens: Balanced
Higher education, transit, historic buildings
AI-assisted · Source-linked · Editorially reviewed · Methodology
Trust note
This article was drafted with AI assistance, reviewed against accessibility.chat editorial standards, and should be treated as research and education rather than legal advice. We prioritize primary sources and correct material errors.

The screen reader user presses Tab. The skip link announces. They activate it. Nothing moves. The focus stays exactly where it was, stranded at the top of the navigation, with no path forward except tabbing through every link on the page.
This is the skip link failure state. It's quiet, invisible to sighted users, and functionally equivalent to removing the skip link entirely.
The automated analysis of wcagrepo.netlify.app/55-link-skip-link (opens in new window) found a page built specifically to demonstrate skip link failures — and it delivers on that premise across three distinct patterns. Each one violates WCAG 2.4.1 Bypass Blocks (opens in new window), and together they represent the most common ways skip links break in production. The page also contains one structural violation: a missing <header> landmark, which maps to WCAG 1.3.6 Identify Purpose (opens in new window) and the broader landmark navigation requirements under WCAG 1.3.1 Info and Relationships (opens in new window).
THE FINDING
The page presents three skip link bug patterns, each isolating a different failure mode:
Bug Pattern 1: Skip link hidden, no focus management. A "Skip to main content" link exists in the DOM but is visually hidden and has no mechanism to move focus to the target element. The link announces in the accessibility tree but activates into nothing.
Bug Pattern 2: Skip link without visual focus indicator. A "Skip navigation" link is present and functional in the DOM, but receives no visible focus style when keyboard focus lands on it. Keyboard users who can see the screen have no indication the link exists or is active.
Bug Pattern 3: Multiple skip links without distinguishing labels. Two links both labeled "Skip" appear in sequence. Screen reader users hear identical announcements with no way to distinguish their destinations.
The problematic code patterns look like this:
<!-- Pattern 1: Target not focusable -->
<a href="#main">Skip to main content</a>
<!-- ... -->
<main id="main">Main content starts here</main>
<!-- Missing: tabindex="-1" on target -->
<!-- Pattern 2: No visible focus indicator -->
<a href="#content" class="skip-link">Skip navigation</a>
<!-- CSS hides focus: .skip-link:focus { outline: none; } -->
<!-- Pattern 3: Identical labels -->
<a href="#section1">Skip</a>
<a href="#section2">Skip</a>
The structural finding: the page has <main> and <nav> landmarks (both passing), but no <header> or ARIA banner landmark. This means assistive technology users navigating by landmarks get an incomplete map of the page.
WHY THIS MATTERS
Skip links exist for one reason: keyboard and switch users should not have to navigate through repetitive content (navigation menus, headers, sidebars) to reach the main content of every page. WCAG 2.4.1 (opens in new window) is a Level A requirement — the baseline. Failing it isn't a nuanced edge case. It's a fundamental keyboard navigation barrier.
Breaking down the user experience for each pattern:
Pattern 1 (broken focus management): A screen reader user activates the skip link. The URL hash updates to #main. But if the target element has no tabindex="-1", browsers won't move programmatic focus to it — only scroll position may change, and even that is inconsistent across browsers. The user's next Tab keypress goes to whatever element follows the skip link in DOM order, not to the main content. The skip link accomplished nothing.
Pattern 2 (no visible focus indicator): A low-vision user navigating by keyboard has no visual feedback when focus lands on the skip link. They can't see it, can't identify it, can't activate it intentionally. This violates both 2.4.1 and WCAG 2.4.7 Focus Visible (opens in new window). The link exists in the DOM but is functionally invisible.
Pattern 3 (duplicate labels): A screen reader user pulls up a list of links on the page (a common navigation pattern in NVDA and JAWS). They hear "Skip" and "Skip" — two identical entries with no distinguishing information. They cannot determine which leads where. This also violates WCAG 2.4.6 Headings and Labels (opens in new window) and WCAG 4.1.2 Name, Role, Value (opens in new window) when the ambiguity extends to interactive element naming.
The missing <header> landmark is a secondary but real barrier. Screen reader users rely on landmark navigation to orient themselves quickly. A page with <nav> and <main> but no <header> creates a structural gap — the banner region that typically contains site identity, primary navigation context, and top-level controls is unannounced.
BEST PRACTICES
Each pattern has a direct fix:
Fix Pattern 1: Ensure focus moves to target
<a href="#main-content" class="skip-link">Skip to main content</a>
<!-- Target must be focusable -->
<main id="main-content" tabindex="-1">
<!-- page content -->
</main>
The tabindex="-1" makes the element programmatically focusable without inserting it into the natural tab order. When the skip link is activated, focus moves to <main> and the next Tab press continues from there.
Fix Pattern 2: Visible focus indicator
.skip-link {
position: absolute;
left: -9999px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
.skip-link:focus {
position: static;
width: auto;
height: auto;
overflow: visible;
/* Never suppress outline */
outline: 3px solid #005fcc;
outline-offset: 2px;
padding: 0.5rem 1rem;
background: #fff;
color: #005fcc;
z-index: 9999;
}
The pattern hides the link off-screen until it receives focus, then renders it visibly. Never use display: none or visibility: hidden on skip links — those remove them from the accessibility tree entirely.
Fix Pattern 3: Distinct, descriptive labels
<a href="#main-nav">Skip navigation</a>
<a href="#main-content">Skip to main content</a>
If the destinations are different, the labels must be different. The ARIA Authoring Practices Guide (opens in new window) consistently emphasizes that interactive elements with identical names but different behaviors create cognitive and navigational barriers.
Fix: Missing header landmark
<header role="banner">
<!-- site logo, primary nav, etc. -->
</header>
The <header> element at the top level of the document automatically carries the banner landmark role. No explicit ARIA needed unless the header is nested inside another sectioning element.
APPLYING THIS
Skip link failures are among the most reliably detectable issues in automated testing — but only partially. Automated tools can confirm a skip link exists and that its target has an id. They cannot reliably detect whether focus actually moves on activation, whether the visual focus indicator meets contrast requirements, or whether duplicate labels create meaningful ambiguity in context. This gap is documented in Beyond Detection: Why Context Separates Automated Testing from Manual Audits — the 37% detection ceiling for automated tools applies directly here.
For development teams:
- Code review check: Any
<a href="#id">Skip...</a>pattern should trigger a review of the target element fortabindex="-1". Make this a PR checklist item. - CSS audit: Search for
.skip-link:focus { outline: none }or any focus suppression on skip link selectors. This is a common copy-paste error from older CSS resets. - Link label audit: Pull all skip links on a page and check for duplicates. If two links share the same visible text, they need
aria-labeloraria-labelledbyto differentiate them. - Landmark audit: Run any page through the NVDA landmark navigation (Insert+F7) or the axe browser extension (opens in new window) to verify the full landmark map. Missing
<header>will surface immediately.
The missing landmark is a quick fix — one element, five minutes. The skip link patterns require slightly more care, but none are architecturally complex. These are the kinds of issues that The Methodology Paradox: Why Automated Testing and Manual Audits Both Fail describes as falling into the gap between tools: automated scanners flag the presence of a skip link as passing, while the actual keyboard experience fails entirely.
CORS PERSPECTIVE
From a balanced CORS lens, this page illustrates a systemic organizational pattern more than a technical one. The community impact is concrete — keyboard users, screen reader users, and switch access users all encounter a skip link that signals accessibility intent but delivers none. Operationally, the fixes are low-cost and high-impact, sitting squarely on the "chop list" of quick wins that teams can deploy without specialized expertise. The risk profile is straightforward: WCAG 2.4.1 is Level A, the baseline, and skip link failures are detectable in standard audits. Strategically, skip links are often the first thing an accessibility auditor checks — getting them right signals that a team understands keyboard navigation fundamentals, not just automated scan compliance. Getting them wrong, especially across three distinct patterns on a single page, signals the opposite.
About the David lens
Boston-based accessibility consultant specializing in higher education and public transportation. Urban planning background.
David is an AI analyst lens, not a human staff member. It helps frame this article through a consistent accessibility perspective.
Specialization: Higher education, transit, historic buildings
View all articles using this lens →Primary source reviewed: https://wcagrepo.netlify.app/55-link-skip-link (opens in new window)
Transparency Disclosure
This article was drafted with AI assistance and reviewed against our editorial methodology. We disclose that process so readers can judge the work clearly.