Your skip link targets don't need tabindex=-1 to work properly

posted on

Recently, someone posted on LinkedIn that skip links are often broken because their target elements are missing a tabindex attribute. I was really surprised to see that because I thought that was an issue of the past. That's why I decided to test it.

The original problem

The author explained in their post that when you use a keyboard and press Enter on a skip link, the page scrolls down to the target, but focus stays on the link. When you press Tab, focus doesn't jump to the target; it jumps to the next focusable element after the skip link. He calls that a “phantom jump”.


<a href="#content">Jump to content</a>
<nav>
    <!-- A bunch of links -->
</nav>
<main id="content">
</main>

They explain that the problem is that the main element is not an interactive element and thus cannot be focused. That's why their proposed solution is adding a tabindex attribute.

<a href="#content">Jump to content</a>
<nav>
    <!-- A bunch of links -->
</nav>
<main id="content" tabindex="-1">
</main>

What the author describes was a problem… a long time ago. As Sara Higley reconstructs, Firefox was the first browser to fix it in 2013, followed by Internet Explorer, and finally Chrome in 2016. I don't know about Safari, but it was long enough ago that I can't remember anymore.

The solution

The fix browsers implemented is a feature called “sequential focus navigation starting point (SFNSP)”. Rob Dodson defines it well in his post “Remove headaches from focus management”.

The 'sequential focus navigation starting point' feature defines where we start to search for focusable elements for sequential focus navigation (Tab or Shift-Tab) when there is no focused area.

Prior to that, there were only two possible starting points.

With SFNSP, there can now be more starting points.

That was a necessary addition because it fixed several fundamental accessibility issues. As mentioned, it's been available in all major browsers for many years and works well. Nevertheless, I want to back that with actual tests. In this blog post, I want to focus only on the scenario where navigating to a page fragment sets the starting point.

Testing

For my test, I created a simple page. My goal was to confirm three outcomes:

<header>
  <a href="#content">Skip</a>
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button>4</button>
  <button>5</button>
</header>

<main id="content">
  <h2>Main content</h2>
  <button>Content</button>
</main>

I was able to confirm all three scenarios in all tested browsers.

Styling

Navigating to a non-interactive page fragment doesn't reveal the element's focus styling, because it's not focused, it's only a starting point. We still have options to style a targeted element in CSS.

:target {
  outline: 2px solid #ccc;
}

Conclusion

Unless I'm missing something (please let me know), I would say it's safe to remove tabindex="-1" from your skip link targets.
I didn't link to the post on LinkedIn because I didn't want to callout the author. It's not about them being wrong, but about the fact that browsers and screen readers receive frequent updates. That's why it's important that you reevaluate the best practices you've been following for years every now and then and check if they still apply. Often, things that were true a couple of years ago aren't true today.