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
(https://github.com/WICG/focus-visible)!
According to the docs, this selector uses two heuristics to determine whether the keyboard is being used:
- a
focus
event immediately following akeydown
event where the key pressed was eitherTab
,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!