2.3. Navigation Shortcuts

Introduction

Let's talk about the websites with a lot of links at the top of the page before the actual main content.

The keyboard-only users are forced to tab through every single link before they can reach the main content. We, as web creators, can make better than that, right?

A common way to bypass this is to create "Skip Navigation Links". The basic concept involves two elements: A trigger and a target.

<!-- Trigger: a link pointing to an #id -->
<a href="#main" class="skipLink">Skip to main content</a>

<!-- Target: A part of the page with the same id -->
<!-- Some browsers will only focus <main> if tabindex="-1" is used -->
<main id="main" tabindex="-1">...</main>

We can visually hide the skip links by default and only show it when focused.

.skipLink:not(:focus) {
  /* hide visually the link using .sr-only styles */
  position: absolute;
  width: 1px;
  height: 1px;
  /* rest of .sr-only styles... */
}

.skipLink:focus {
  /* link styles when it's focused */
}

This skip link must be one of the first elements in the DOM to be quickly accessed through the keyboard.

Exercise

In the exercise page, let's create a "Skip Navigation" link to jump directly to the main section of the page.

🎯 Goal: Create navigation shortcuts through the page.

Bonus

#1 Target styling

When creating skip links using id #, we can style using the CSS pseudo-selector :target.

🎯 Goal: Use :target to style the main area when it's focused.

Limitation: With this approach, you'll notice the target animation only works once. Because the #main selector is added to the page URL, when triggered again it will be ignored, unless the URL no longer contains that selector. To overcome this, JS would be required.

#2 Using Tabindex

We can create "Skip Navigation" for other scenarios. For example, in a "Back to Top" shortcut.

Usually people implement this widget with a scroll mechanism but forget about the keyboard aspect.

🎯 Goal: In the "Back to Top", add keyboard support by using tabindex and JavaScript.

🍀 Toggle hint #1 - JS focus behavior

When using elTitle.focus(), you'll notice the scroll to top is not smooth anymore. The focus() specs accepts a parameter that solves this problem… ;)

#3 Scroll behaviors

The scroll to top is smooth, always. Based on what we've learned so far, do you think this behavior is inclusive?

That's right… it doesn't respect the user's motion preferences! In JavaSacript is possible to detect if a media query matches, using window.matchMedia().

🎯 Goal: Modify the scroll behavior to respect the user preference.

🍀 Toggle hint #1 - Using JS media

The media you'll need to use is:

const motionReduced = window.matchMedia("(prefers-reduced-motion: reduce)");

if (motionReduced.matches) {
  /* ... */
}

Further reading

WCAG Success Criterion

Exercise takeaways

(After the exercise) Reveal takeaways