Hiding the outline or :focus ring in an accessible way

José M. Pérez

José M. Pérez / August 14, 2017

2 min read10,808 views

Last week I came across Removing that ugly :focus ring (and keeping it too). It's a really good post about outline, that CSS property lots of devs tend to hide. The post explains some a11y-friendly alternatives to not display it, and show it when needed.

In the past I have made the same mistake of hiding the outline altogether, but no more!

A few months ago I came across a similar technique David Gilbertson describes, while inspecting the markup on Youtube.com. They take accessibility seriously and their player is a very good example to get inspiration from.

I then applied it to one of the Spotify sites I work on. Take this Spotify page as an example. This is how it works:

  1. Add a no-focus-outline CSS class to the <html> element.
  2. Hide the outline using CSS only in <a> and <button> elements that descend from that class.
  3. When tabbing, remove the CSS class.

The complete code:

CSS

.no-focus-outline a:focus,
.no-focus-outline button:focus {
  outline: none;
}

JS

// Listen to tab events to enable outlines (accessibility improvement)
document.body.addEventListener('keyup', function(e) {
  if (e.which === 9) /* tab */ {
    document.documentElement.classList.remove('no-focus-outline');
  }
});

And a video showing what it looks like when tabbing:

Some additional a11y improvements are that I apply the same effect on hover and on focus, like when going through the "More by ..." albums section. Last, but not least, the track row acts as a button to start the playback.

These are some small touches that very few people will realise, but are not difficult to implement and can have a very positive impact for some users.