What is a skip link?

A skip link is a hidden link that becomes visible on keyboard focus, allowing users to bypass repetitive navigation and jump directly to main content. It's required for WCAG 2.4.1 (Bypass Blocks).

Who benefits

Basic implementation

Step 1: Add the HTML

Place this as the first element inside your <body> tag:

<body>
  <a href="#maincontent" class="skip-link">Skip to main content</a>
  
  <!-- Your header/navigation here -->
  
  <main id="maincontent">
    <!-- Main page content -->
  </main>
</body>

Step 2: Add the CSS

.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #0C234B;
  color: #ffffff;
  padding: 8px 16px;
  z-index: 10000;
  text-decoration: none;
  font-weight: bold;
  transition: top 0.3s ease;
}

.skip-link:focus {
  top: 0;
  outline: 3px solid #AB0520;
  outline-offset: 2px;
}

Step 3: Ensure target exists

Your main content area must have the matching ID:

<main id="maincontent">
  <h1>Page Title</h1>
  <!-- Content -->
</main>

Enhanced version with multiple targets

For complex pages, you may want multiple skip links:

<div class="skip-links">
  <a href="#maincontent" class="skip-link">Skip to main content</a>
  <a href="#search" class="skip-link">Skip to search</a>
  <a href="#footer-nav" class="skip-link">Skip to footer</a>
</div>

CSS for multiple skip links

.skip-links {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10000;
}

.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #0C234B;
  color: #ffffff;
  padding: 8px 16px;
  text-decoration: none;
  font-weight: bold;
  white-space: nowrap;
}

.skip-link:focus {
  position: static;
  display: inline-block;
  outline: 3px solid #AB0520;
  outline-offset: 2px;
}

WordPress implementation

Most WordPress themes include skip links. To add or modify:

In header.php

<body <?php body_class(); ?>>
  <a class="skip-link screen-reader-text" href="#primary">
    <?php esc_html_e( 'Skip to content', 'theme-name' ); ?>
  </a>

In style.css

.screen-reader-text {
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  word-wrap: normal !important;
}

.screen-reader-text:focus {
  background-color: #0C234B;
  clip: auto !important;
  clip-path: none;
  color: #ffffff;
  display: block;
  font-size: 1rem;
  height: auto;
  left: 5px;
  line-height: normal;
  padding: 15px 23px 14px;
  text-decoration: none;
  top: 5px;
  width: auto;
  z-index: 100000;
}

Drupal implementation

Drupal core themes typically include skip links. Customize in your theme's template:

In page.html.twig

<a href="#main-content" class="visually-hidden focusable skip-link">
  {{ 'Skip to main content'|t }}
</a>

React / SPA implementation

For single-page applications, ensure the skip link target is focusable:

// SkipLink.jsx
function SkipLink() {
  const handleClick = (e) => {
    e.preventDefault();
    const main = document.getElementById('maincontent');
    if (main) {
      main.tabIndex = -1;
      main.focus();
      main.scrollIntoView();
    }
  };

  return (
    <a href="#maincontent" className="skip-link" onClick={handleClick}>
      Skip to main content
    </a>
  );
}

// In your main layout
function Layout({ children }) {
  return (
    <>
      <SkipLink />
      <Header />
      <main id="maincontent" tabIndex="-1">
        {children}
      </main>
      <Footer />
    </>
  );
}

Testing your skip link

  1. Load the page and press Tab
  2. Skip link should become visible as first focusable element
  3. Press Enter to activate
  4. Focus should move to main content
  5. Next Tab should go to first link/button in main content

Common issues

Problem Solution
Skip link not visible on focus Check CSS :focus styles and z-index
Focus doesn't move to target Ensure target has matching ID
Focus moves but next Tab goes to top Add tabindex="-1" to target element
Skip link covered by sticky header Increase z-index or adjust positioning

Complete example

Copy this complete HTML page structure:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Page Title</title>
  <style>
    .skip-link {
      position: absolute;
      top: -40px;
      left: 0;
      background: #0C234B;
      color: #ffffff;
      padding: 8px 16px;
      z-index: 10000;
      text-decoration: none;
      font-weight: bold;
    }
    .skip-link:focus {
      top: 0;
      outline: 3px solid #AB0520;
      outline-offset: 2px;
    }
  </style>
</head>
<body>
  <a href="#maincontent" class="skip-link">Skip to main content</a>
  
  <header>
    <nav>
      <!-- Navigation links -->
    </nav>
  </header>
  
  <main id="maincontent">
    <h1>Page Title</h1>
    <!-- Main content -->
  </main>
  
  <footer>
    <!-- Footer content -->
  </footer>
</body>
</html>

Resources