A skip link gives people a direct route past repeated interface content. It is especially useful for someone navigating with a keyboard who would otherwise need to move through the same header controls and navigation links each time they open another page.
Imagine someone exploring a website without a mouse. They read one page, follow a link, and arrive at another. Before reaching the new article or service information, keyboard focus moves through the same logo link, account controls, search button, and primary navigation they encountered on the previous page.
The navigation remains useful, but it is not where the person wants to go this time. A clearly labeled “Skip to main content” link near the beginning of the page lets them move past that repeated block and continue their task.
How a skip link works
A basic skip link uses the same link-and-target relationship as other anchor links and fragment identifiers.
The link contains a fragment identifier in its href value:
<a href="#main-content">Skip to main content</a>
The destination has a matching, unique id:
<main id="main-content">
...
</main>
When the link is activated, the browser finds the element whose id is main-content and navigates to that part of the document. The two values must match exactly, and the destination ID must not be duplicated elsewhere on the page.
A useful implementation must account for more than visible scrolling. After activating the link, the person should be left at a meaningful destination, and subsequent keyboard navigation should continue from that area rather than returning to the controls that were meant to be bypassed.
The destination is usually the page’s <main> element. This establishes a stable relationship between the skip link, the document’s primary content, and its main landmark.
A practical skip-link implementation
The following example places a descriptive skip link before the site header. Its destination is the main content region.
<body>
<a class="skip-link" href="#main-content">
Skip to main content
</a>
<header>
<a href="/">Example Site</a>
<nav aria-label="Primary navigation">
<ul>
<li><a href="/about/">About</a></li>
<li><a href="/resources/">Resources</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
</header>
<main id="main-content" tabindex="-1">
<h1>Page title</h1>
<p>The page’s distinct content begins here.</p>
</main>
</body>
The skip link can remain visible at all times. That is a valid and often straightforward design choice. If the design conceals it visually until it receives focus, the concealment method must preserve keyboard access.
.skip-link {
position: fixed;
inset-block-start: 1rem;
inset-inline-start: 1rem;
z-index: 1000;
padding: 0.75rem 1rem;
color: #ffffff;
background: #1b1b1b;
font-weight: 700;
text-decoration: underline;
}
.skip-link:not(:focus) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
white-space: nowrap;
border: 0;
clip-path: inset(50%);
}
.skip-link:focus {
outline: 3px solid #f4c542;
outline-offset: 3px;
}
#main-content {
scroll-margin-block-start: 6rem;
}
#main-content:focus {
outline: 3px solid currentColor;
outline-offset: 0.25rem;
}
This CSS keeps the link available to keyboard navigation while visually reducing it when it does not have focus. When focus reaches the link, it appears near the top of the viewport with a clear focus indicator.
A skip link should not be hidden with display: none, the HTML hidden attribute, or visibility: hidden. Those techniques ordinarily remove the link from keyboard navigation as well as visual presentation.
Why the destination uses tabindex="-1"
The <main> element is not ordinarily part of the sequential tab order. Adding tabindex="-1" makes it a possible focus destination without adding it to the normal sequence of elements reached by repeatedly pressing Tab.
This can make the transition more explicit: the browser follows the fragment link to the main element, focus can be placed on that destination, and the next keyboard action can continue from the main-content area. The focus outline in the example also provides visible confirmation of the destination.
Browser behavior and application code can affect fragment navigation, so this detail should still be tested in the website’s representative browsers. Avoid using positive values such as tabindex="1" to manufacture a custom navigation order. Positive tabindex values can separate keyboard behavior from the document’s meaningful source order and become difficult to maintain.
Allowing room for a fixed header
A sticky or fixed header can cover the top of a fragment destination after navigation. The example uses scroll-margin-block-start to reserve space when the browser scrolls the main element into view.
The appropriate value depends on the actual header. Responsive layouts may require different spacing at different viewport sizes. The important review question is whether the destination and its first meaningful content remain visible, not whether a particular CSS value was used.
How to test a skip link
Return to the person opening another page. They already know that the site header exists and want to continue into the new content. Testing should follow that complete interaction rather than checking only whether the viewport moves.
- Start at the beginning of the page. Load the page and use the keyboard to begin navigating. On many desktop browsers, pressing Tab will move focus to the first page control, although browser settings can affect which elements receive focus.
- Confirm that the skip link appears. It should become clearly visible when focused. Check that it is not clipped, placed off-screen, or covered by a header, cookie notice, toolbar, or other layered content.
- Read the link label. “Skip to main content” identifies both the action and destination. Labels such as “Skip” or “Click here” provide less useful context.
- Activate the link. Press Enter and confirm that the main-content destination is reached.
- Check the visible destination. The page title or beginning of the main content should not be hidden behind a fixed element. A visible focus treatment can help confirm where the transition ended.
- Continue with the keyboard. Press Tab again and examine where focus goes. It should proceed from the destination toward the next relevant focusable element in or after the main content, rather than restarting in the bypassed header.
- Repeat the test across representative templates. Check articles, search results, forms, product or service pages, and other layouts that use different main-content structures.
Common failures to look for
- The destination ID is missing or has changed. The URL may gain a fragment such as
#main-content, but the browser has no matching element to reach. - The link receives focus but remains invisible. A clipping rule, transform, stacking problem, or surrounding container may keep the focused link outside the visible interface.
- The page scrolls, but keyboard progression remains unhelpful. Visible movement alone does not establish that focus and subsequent navigation continue from the intended destination.
- A sticky header obscures the destination. The browser reaches the correct fragment, but the heading or focused element is hidden beneath a fixed region.
- The feature works on one template only. Another template may omit the destination ID, place it on an unsuitable wrapper, or use a different page structure.
Keyboard testing is a necessary part of review. Testing with representative screen readers and browser combinations can provide additional information about how the link, landmark, destination, and content are announced and navigated.
Template maintenance and additional destinations
Skip navigation usually belongs in a shared site template because the content it bypasses is also shared. Template-level placement makes the feature consistent, but it also means that common design changes can affect every page.
Review the skip-link interaction after changes involving:
- header navigation or utility controls;
- sticky and fixed positioning;
- stacking order and overlays;
- main-content wrappers or destination IDs;
- client-side routing and script-driven page transitions;
- responsive breakpoints; and
- keyboard focus styles.
A single “Skip to main content” link is often sufficient. Some interfaces have another repeated region that creates a substantial navigation barrier, such as an unusually large filter panel. In that case, an additional bypass destination may be useful.
Each additional skip link should correspond to a real navigation need. A long sequence of bypass controls can become another repeated block that people must move through. The goal is a short, understandable route into the work of the page.
A small feature that preserves continuity
The person in the opening example has already encountered the website’s navigation. On the next page, they may want to use it again, or they may want to continue directly into the new content. A skip link preserves that choice.
The implementation is small: a descriptive link, a stable destination, visible focus treatment, and behavior that has been checked with a keyboard. Its usefulness depends on the relationship among those pieces. When the link removes repeated effort and leaves the person ready to continue, bypass navigation is doing its work.
For broader guidance on focus sequence and keyboard operation, see Keyboard Navigation Best Practices and the URLMD accessibility neighborhood.