Clickable elements like buttons have an outline by default when targeted by the keyboard or activated by the mouse. Especially the latter behavior is not so popular, because it's ugly. Especially, when a click on a button doesn't load a new page and the outline will remain until you click somewhere else.
A cheap trick to prevent this behavior is following:
*:focus {
outline: 0;
}
Cool, there's no ugly outline after clicking an element anymore! But wait... There's a huge problem with this approach: you screw keyboard users. This outline is pretty important and common to highlight the current position while navigating with the keyboard. Not everybody uses a mouse and by hiding the outline you exclude those people.
A simple solution
I'm building my new website with React right now and I try to take care of accessibility as good as possible. And when I tried to use the keyboard on my website I didn't see my current position. Why? Because I used the cheap trick mentioned above... Then I deleted those few lines and it worked but I was not a fan of the impact on the design.
My plan was to show the outlines for keyboard users, but not when using a mouse. In the end, I came up with a simple solution based on react hooks and this is how it looks like:
Nice, isn't it? Do you want to know how I implemented it? Yes?! Here we go!
Step 1
At first we need a state hook to differ if a mouse was used or not:
const [mouseDown, setMouseDown] = useState(false);
Step 2
Then we need an effect hook to listen to the mousedown
and the keydown
event to set then the right state of mouseDown
:
useEffect(() => {
document.addEventListener('mousedown', function (event) {
setMouseDown(true)
});
document.addEventListener('keydown', function (event) {
setMouseDown(false)
});
}, []);
Step 3
Now we add the class mousedown
to the wrapper of your project (here we use App
) just when the mouse was clicked:
<App className={mouseDown ? 'mousedown' : ''}>
Step 4
And the final step is to remove the outline for all elements inside App
when using a mouse:
App.mousedown *:focus {
outline: 0;
}
Of course, you can change the color of the outline (like I did for the dark mode) or style that state completely different, but keep in mind to set the targeted element apart from the rest of the elements. My recommendation is to stick close to default behavior.
Example
To demonstrate how it works you can check out this Codepen snippet. Just click inside and navigate with the Tab
key and click the buttons. You can toggle between the general behavior and my little fix:
I hope this post was helpful and if you have any questions or feedback just let me know! Thanks for reading :)
Top comments (0)