Skip Navigation

A simple same-page anchor that allows users to skip past lengthy blocks of navigation or controls.
Skip to main content


The skip navigation pattern is a simple internal link that allows users to navigate from one part of the page to another.

A skip link is most commonly used by keyboard users to skip past the main navigation in the site header. A skip link may also appear elsewhere on the page, as in the "see details" link on eBay's view item page.

It is also not uncommon to see a "Back to Top" link in the footer of a website. This is also an instance of the skip pattern.

Working Examples

You can take a look at the skip pattern in action on our examples site.

Best Practices

Link must skip keyboard and screen reader users to target element.

Link may be hidden from view until focused with keyboard (if the skip-to link is of little use to mouse or touch users).

Interaction Design

This section provides interaction design for keyboard, screen reader and pointing devices.


Activating the skip link moves keyboard focus to the target element. The default browser behaviour here is to NOT show a focus indicator.

After activating the skip link, pressing TAB key moves keyboard focus to first interactive element after the target element and restores focus indicator.

Screen Reader

Activating the skip link moves virtual cursor to the target element and screen reader will announce the contents of that element.

After activating the skip link, moving screen reader virtual cursor forwards will move virtual cursor to the next element after the target element.


Activating the skip link scrolls page to target element.

Developer Guide

Our implementation follows the Progressive Enhancement strategy; we build in a layered fashion that allows everyone to access the basic content and functionality of a web page.

The three layers are:

  1. Content (HTML)

  2. Presentation (CSS)

  3. Behaviour (JS)

The skip-to content is fully accessible without CSS and JavaScript.

Content (HTML)

Our content contains a source link and a target element.


In our target element we specify a unique id, and set a tabindex value of -1.

<div id="mainContent" role="main" tabindex="-1">
<!-- all of your main page content goes here -->
</div >

Without the tabindex, a screen reader's virtual cursor may get left behind on the skipto link after activation. The tabindex of -1 forces the screen reader to move to and read the target element.

Note that there are some issues with adding the tabindex permanently, please see the JavaScript section further below for details on how to add it dynamically.


Our source link references the target id:

<a class="skipto" href="#mainContent">Skip to main content</a>


Our HTML is now complete, and we have a fully functional skip to link without any JavaScript.

How does this work without JavaScript? If the URL contains a hash fragment, the browser will set keyboard focus on the element with matching ID. The tab index of negative one also forces the screen reader virtual cursor to move to the target element.

Presentation (CSS)

The goal of the presentation layer is to hide the skip to link until it has keyboard focus.

Hiding Offscreen

We use a CSS clipping technique to hide the element offscreen:

.skip {
position: absolute;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding: 0;
border: 0;
height: 1px;
width: 1px;
overflow: hidden;


To reveal, we update these styles using the :focus pseudo selector:

.skip:focus {
clip: none;
height: auto;
width: auto;

Hiding Focus Outline

You may notice that if you click with your mouse on the target area, a focus indicator appears around the element. This is due to the tabindex value of -1.

We can remove this outline with CSS:

.skip-target:focus {
outline: 0 none;

Note that this is one of the very few times (perhaps the only time?) when it is okay to remove the focus outline of an element.


Our CSS is now complete. The skip to link now only appears when it has keyboard focus.

Behaviour (JavaScript)

In our experience, we have witnessed some edge-case issues caused by the permanent presence of tabindex="-1", especially when on the main content element (i.e. role="main"). To workaround these issues, the tab index value can be added and removed dynamically, using JavaScript.

skipEl.addEventLisetner('click', function (e) {
targetEl.setAttribute('tabindex', '-1');
// remove tabindex on next blur
targetEl.addEventListener('blur', function(e) {
},{ once: true });


Why do we need tabindex="-1"? All modern browsers move keyboard focus without it.

All modern browsers do indeed now move the keyboard focus from the link to the target. This is great news for sighted keyboard users. However, we have found that in certain cases a screen reader will get left behind on the link, and not fully moved to the target. A tab index of negative one seems to force the screen reader to fully move onto the target element. So we think of this as some additional "focus management".