Building More Accessible UIs: Focus Visible

How many times have you built a UI just to have the button have this nasty default outline when someone clicks the button.

Probably more than not, you just did outline: none. That will remove the outline but now if you have users that are using a keyboard and tabbing they will not longer be able to tell that item is active.

Today’s Hacks

For the detail obsessed, we’ve worked around this by adding a slew of events around the elements and document to coordinate who caused what. This is a partial code snippet from a popular library showing just the sheer complexity of this.

Hello Focus Visible

Most of us don’t have time to worry about these details. Fortunately there is a new CSS selector that will allow us to target CSS for only keyboard focused elements. Say hello to :focus-visible (!

According to the docs, this selector uses two heuristics to determine whether the keyboard is being used:

  • a focus event immediately following a keydown event where the key pressed was either Tab, Shift + Tab, or an arrow key.
  • focus moves into an element which requires keyboard interaction, such as a text field

We can use it like this:

Browser Support

Sadly browser support has not caught up yet though, according to caniuse there is only 5% coverage.

Luckily, there is a polyfill plugin and a PostCSS processor that we can use to start taking advantage of this feature today!

In the link I posted above, you can see the proposal and where to get the polyfill. This will add a special CSS class you can use but there is also a PostCSS plugin that will allow you to write the proposed syntax today! Now your probably thinking, that can get a little dicey using early stage proposals but if you look at the downloads on NPM every week this is starting to take off!

Wrapping Up

In closing, this is a great new feature that will allow us to remove hacks and make our UI more accessible!

I hope you enjoyed the post, if you liked it follow me on Twitter and Github for more JavaScript tips/opinions/projects/articles/etc!