Add focus-visible to your React application

🦋Allegra
3 min readMay 17, 2020

And make it more accessible for keyboard-only users.

It’s a very common anti-pattern to use outline: none to disable default browser’s focus indicator styling (yes, that blue outline you see around buttons and inputs on Chrome) without providing any alternative focus styles.

If might be ok for your side projects but not for a consumer facing production app.

I will show you how to add it to your React application and will explain why it’s an important thing to have. Code first, for those that already know the ‘why’.

Code for a React application with styled-components.

npm i focus-visible 

Install the package and then import it in your application index.js or App.js file.

import 'focus-visible';

This is the package we’re installing: https://github.com/WICG/focus-visible

If you are using Typescript, then you will need to declare module in one of your declaration (d.ts) files.

declare module 'focus-visible';

Then we create a wrapper with these class names:

return (<FocusVisible className="js-focus-visible focus-visible">  //your app here</FocusVisible>);

FocusVisible is a styled component:

const FocusVisible = styled.div`  &.js-focus-visible :focus:not(.focus-visible) {     outline: none;  }  &.js-focus-visible .focus-visible {     outline: none;     border: 3px solid #528deb;  }`;

Here we are saying that we don’t want the default outline on mouse click focus, but if a user is navigating with a keyboard, then apply border: 3px solid #528deb; or any other style you’d like your users to see. It has to be clearly visible, so choose a good contrasting colour.

Custom focus outline will only be visible for keyboard users

I chose #528deb because it’s very similar to Chrome’s default outline’s colour.

Using one consistent style for your focus indicator is a good practice, because some users might find it confusing to follow a changing style. Accessibility is all about being inclusive.

The why

The focus indicator (focus ring) identifies the currently focused element on your page. For users who are unable to use a mouse, this indicator is extremely important because it acts as a stand-in for their mouse-pointer.

The general rule of thumb is that any control a user can interact with or provide input to should aim to be focusable and display a focus indicator. If a keyboard user can’t see what’s focused, then they have no way of interacting with the page.

Summary:

1.We should not hide a focus indicator (often done with :focus { outline: none; } ❌).
2.We don't want to have focus rings for mouse users, but they are essential for users who use keyboard to navigate.

Focus-visible is the best option because a visual indication of what has focus is only interesting to a user who is using the keyboard to interact with the page.

Manual testing

Use TAB button to navigate (TAB + shift to go backwards), you should see the focus indicator as per screenshot above but when you click a button with a mouse, there should be no indicator.

Once you have this working, you can test what your app is like to navigate with keyboard only.

👏🏽 thanks for reading

Photo by Aryan Dhiman on Unsplash

--

--