On each web page, is a skip link or quick access link to the main content area present (except in special cases)?

A keyboard user arrives on your page and starts tabbing. The main menu contains 12 links, the breadcrumb 3, the search bar 2. Before reaching the article title they want to read, they must press Tab 17 times. And repeat on every new page. The skip link solves this problem with a single keystroke.

Criterion 12.7 requires a mechanism to either bypass or reach directly the main content zone (the visible <main> element). Two approaches are valid: a skip link placed just before <main> in the source code, or a quick access link that becomes visible as soon as it receives keyboard focus.

Test 12.7.2 goes further. The link must appear in the same place on each page, in the same relative order in the source code, be visible on focus, and actually work. A link pointing to an id absent from the DOM does not move focus: it fails the criterion even if visually present.

In practice: place <a href="#content" class="skip-link">Skip to content</a> first in the <body>, give id="content" to your <main>, and add tabindex="-1" to this <main> to guarantee focus moves there in all browsers, Safari included.

2 tests to confirm that a skip link allows bypassing repetitive blocks

Skip or quick access link to main content

  1. Locate the visible <main> element on the page.
  2. Verify that at least one of these two conditions is met: a. A link directly precedes <main> in the source code and allows skipping it (skip link). b. A quick access link becomes visible when it receives keyboard focus (Tab from the page start).
  3. Result: if neither condition is met, the test fails.

Consistency, visibility and functionality of skip link

Based on the skip link or quick access link identified in test 12.7.1, verify the following 4 points:

  1. Consistent position: the link occupies the same visual place on all pages of the site.
  2. Stable order in code: the link always appears in the same place in the client-side generated source code.
  3. Visible on focus: the link appears when it receives focus by tabulation (even if hidden visually at rest).
  4. Functional: activating the link actually moves focus to the target zone. If all 4 conditions are met, the test is validated.

Examples

❌ Non-compliant : Skip link hidden with display:none

<a href="#main-content" class="skip-link">Skip to content</a>
 
<style>
.skip-link {
  display: none;
}
</style>

A link with display:none is invisible to everyone: sighted users, keyboard users, and screen readers. It no longer exists in the accessibility tree. Its presence in the source code fulfills no obligation: the criterion requires a link visible on focus, not a dead link in the HTML.

✅ Compliant : Skip link visible on focus with focusable target

<a href="#main-content" class="skip-link">Skip to main content</a>
 
<header>
  <nav aria-label="Main navigation">
    <!-- navigation links -->
  </nav>
</header>
 
<main id="main-content" tabindex="-1">
  <h1>Page title</h1>
  <p>Main content...</p>
</main>
 
<style>
.skip-link {
  position: absolute;
  top: -44px;
  left: 0;
  background: #000000;
  color: #ffffff;
  padding: 8px 16px;
  z-index: 9999;
  text-decoration: none;
  transition: top 0.2s;
}
.skip-link:focus {
  top: 0;
}
</style>

The link is off-screen at rest but remains in the accessibility flow. On the first tab, it moves up and becomes visible. The tabindex="-1" attribute on <main> is essential: without it, Safari does not move focus to the target element even though scrolling occurs, and the screen reader user remains stuck after the link.

❌ Non-compliant : Skip link pointing to a non-existent id

<a href="#content">Skip to content</a>
 
<header>
  <nav><!-- navigation --></nav>
</header>
 
<!-- id does not match href -->
<main id="main-content">
  <h1>Article</h1>
</main>

The link points to #content but the <main> has id="main-content". The browser cannot find the target: neither scroll nor focus movement occurs. The link is technically present and visible on focus, but the "functional" point of test 12.7.2 fails. This type of error often goes unnoticed during refactoring.

Tips and pitfalls

⚠️ visibility:hidden and display:none completely invalidate the link

Both properties remove the element from the accessibility tree. The link no longer exists for screen readers or keyboard navigation. This is error number 1 found in audits. The correct technique: position: absolute; top: -40px at rest, with return to top: 0 on the :focus selector. The link remains in the accessibility flow while being visually invisible.

⚠️ Missing tabindex="-1" on the target

Without tabindex="-1" on <main>, Safari and certain Chrome versions do not move focus to the target element: scrolling may occur, but focus remains on the skip link. The screen reader user ends up after the link, not in the content. Always systematically add tabindex="-1" to any element targeted by an anchor that is not natively focusable.

💡 First child of body: the only safe position

Place the skip link as the very first child of the <body>, before any <header>, injected <script>, or wrapper <div>. This is the only position that guarantees it precedes repetitive zones. A skip link placed after the <header> no longer allows bypassing that header.

⚠️ Single-page site: the criterion may be non-applicable

On a site consisting of a single page without repetitive navigation or blocks preceding the main content, the criterion may be declared non-applicable. The evaluation is contextual: if a keyboard user has no obstacles to traverse before reaching the content, the skip link provides nothing to them. Document this choice in the accessibility statement with explicit justification.

⚠️ Direct arrival on a section via anchor link

If a user arrives on the page via an anchor link (for example article.html#results), they already land in the content: skip links they did not traverse pose no problem. This scenario does not exempt implementing the skip link for arrivals from the top of the page, which remain the most common case.

Frequently asked questions

What visibility does RGAA require for a skip link: permanent or only on focus?

Visible on focus is sufficient to satisfy RGAA 12.7. The link can be hidden visually at rest as long as it appears as soon as it receives focus by tabulation. Some stakeholders or brand guidelines may require it to always be visible: this exceeds the criterion requirements but poses no compliance issue.

How to test that a skip link is functional according to RGAA 12.7 criteria?

Open the page in a browser, press Tab once on load. The link must appear. Press Enter. Press Tab again: the next focused element must be in the main content, not in the navigation. With a screen reader (NVDA or VoiceOver), the cursor must announce the first element of the <main> after link activation.

How to structure skip links RGAA when a site has multiple repetitive zones?

No. Criterion 12.7 requires only one link allowing access to the main content. A single <a href="#content">Skip to content</a> is sufficient. Skip links to other zones (navigation, search, footer) fall under criterion 12.6, which is a separate criterion.

How to maintain a functional RGAA skip link in an SPA (React, Vue, Next.js)?

Only if focus is managed correctly after each route change. After internal navigation, the #content anchor must exist in the rendered DOM and focus must be moved manually (to <main> or <h1>). This is the most common failure point in JavaScript applications: systematically test the link after several internal navigations, not only on initial load.

Which label to choose for an RGAA skip link: generic or specific to the target zone?

"Skip to content" or "Skip to main content" are both explicit and compliant with RGAA criteria 6.1 and 6.2 (link label). Avoid vague wording like "Skip" or "Bypass". The text must allow a screen reader user to understand the destination before activating the link.

References