Skip to content

Accessible Skip Links

Chris Harvey edited this page Sep 15, 2017 · 1 revision

Skip links allow non-sighted users and users of mobile devices to easily jump to different parts of a document without having to read or scroll through non-pertinent information. There are three main types of skip links: Skip to Main Content, Jump to Top, and Internal Permalinks.

Skip to Main Content

The “Skip to Main Content” link points to the main content of the page. It should be at the top of the document (the first child of body), so that users can access it quickly.

<body>
  <a class="h-Hidden" href="#main">skip to main content</a>
  <header>
    <!-- site header content, stuff that is skipped -->
    <h1>Site Title</h1>
    <nav><h1>Site Navigation</h1></nav>
  </header>
  <main id="main">
    <!-- skip link points here -->
    <header>
      <!-- page header content, not skipped -->
      <h1>Page Title</h1>
      <nav><h1>Internal Navigation / Contents</h1></nav>
    </header>
    <!-- main content -->
  </main>
</body>
.h-Hidden:not(:focus) {
  position: absolute;
}
.h-Hidden {
  left: -999999px;
}

The link points to the fragment identifier #main, which is the ID of the <main> element in the most common case (however you may put this ID on any element if there are zero or multiple <main> elements in the document.) The link should be exposed to screen readers, but hidden from visual media so that they aren’t a distraction to sighted users. The helper class .h-Hidden achieves this.

Notice also that the link is exposed to sighted users when it’s focused, so that they can see it when tabbing through links.

Jump to Top

The “Jump to Top” link allows users to wrap back to the beginning of the document. It should be the last content in the document, as the last child of body, or it may come before all the <script> tags at the bottom. What’s important is that it comes after all the content in the document.

It points to the fragment identifier #top, which browsers should interpret as the top of the page. Some browsers don’t implement this automatic frag id very well (see this Chrome bug …), so you should write it manually on the <body> tag.

<body id="top">
  <!-- skip link points here -->
  <header>
    <!-- site header content -->
  </header>
  <main>
    <!-- main content -->
  </main>
  <a href="#top">jump to top</a>
</body>

This link could also be helpful for desktop and mobile users with mobility and/or tactile concerns. Thus the link should be fixed to the bottom of the screen.

body > a:last-of-type { /* TODO: use a class selector instead */
  position: fixed;
  bottom: 0;
  right: 0;
}

Internal Permalinks

Internal Permalinks point to internal sections of a document. This can be useful in documents that are very long, that have many sections, or that serve as an aggregate of independent articles. They are also useful for pointing users to the desired section on the page.

The link should go inside the top-most heading of its section, while its frag id is put on the section itself.

<section id="benefits-gum-chewing">
  <h1>Benefits of Gum Chewing
    <a class="c-Permalink h-Hidden" href="#benefits-gum-chewing" aria-label="permalink">&sect;</a></h1>
  <!-- section content -->
</section>
<section id="drawbacks-gum-chewing">
  <h1>Drawbacks of Gum Chewing
    <a class="c-Permalink h-Hidden" href="#drawbacks-gum-chewing" aria-label="permalink">&sect;</a></h1>
  <!-- section content -->
</section>
h1:hover > .c-Permalink {
  position: static;
}

A few notes on internal permalinks:

  1. The frag id goes on the containing <section> tag (or <article>, <aside>, or <nav>). Alternatively you may put it on the <h1> tag itself, but being on the section makes for easier identification and debugging in the DOM.
  2. Class .h-Hidden acts as before, hiding the element from sighted users unless focused upon.
  3. Similar to .h-Hidden, the component class .c-Permalink exposes the link when h1 is hovered over. This allows sighted users to click the link to load the target URL, but also prevents the links from visually cluttering the screen.
  4. The content of the link is the section symbol § (&sect;), for brevity. You can also use the pillcrow symbol ¶ (&para;), or anything else. If using a symbol instead of text, be sure to add [aria-label] to provide meaningful content. You can even use a more verbose value, such as aria-label="jump to section 'Benefits of Gum Chewing'".