One thing that inevitably makes it’s way into our QA process on any project is the unexpected appearance of focus rings.

Example of a focus ring

A wild focus ring appeared

We’ve had a lot of discussions about how to handle these. The project manager and designer often suggest removing them. While that would be the easy solution, it would be a web design anti-pattern. Default focus rings are provided by all browsers so that keyboard users can determine which element is currently in focus. In fact, focus rings are required to meet accessibility standards:

Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.

- W3 Web Content Accessibility Guidelines

Even when we decide not to remove focus rings, designers are usually unhappy with the default styles. One question that came up recently is if focus ring styles are made for keyboard users to keep track of the focus on the page, why do they need to show up when I click on an element? Can we add focus rings for keyboard users only?

The answer is yes! We can use the :focus-ring polyfill to add focus rings only when a user is navigating with a keyboard.

How to use the :focus-ring polyfill

Here’s how you can implement the :focus-ring in your projects right now.

If you are using ES6 modules, install the polyfill via npm: npm install --save wicg-focus-ring

Import the module into your main JavaScript file:

import 'wicg-focus-ring';

When your page loads, your <body> will get a class of .js-focus-ring so you can conditionally hide default focus rings only if the polyfill is loaded. Additionally, when you are navigating via keyboard, focused elements will get a class of .focus-ring.

Now we can add our css:

// override UA stylesheet, only when polyfill is loaded
.js-focus-ring :focus:not(.focus-ring) {
    outline-width: 0;
}

// establish desired focus ring appearance for appropriate input modalities
.focus-ring {
  outline: 2px solid $bright-brand-color;
}

Other Resources


Have any comments or questions about this post? Send them to me via email hi@benrobertson.io or on Twitter @banquos_ghost.