Look at that! The :focus-visible
pseudo-selector is now supported in Firefox, as of version 85 which shipped yesterday. I had to rush over to the MDN Docs just to confirm, and yep, the :focus-visible
page has been updated to reflect the news.
What’s so cool about :focus-visible
? It’s all about the blue focus ring that displays around elements that are in focus. It’s sort of a happy medium between loving the outline for accessibility purposes (gotta know what element is selected when tabbing on a keyboard) but not-really-loving how it looks (gotta have everything follow brand).
The strategy has largely been an all-or-nothing choice between using a custom outline
when any element is in :focus
(great, but that means for both keyboard tabbing and mouse clicks) or ditching the outline
altogether (not great, like ever). :focus-visible
accomplishes the same thing as :focus
, but uses a browser’s knowledge of user inputs (or heuristics) to determine whether the focus is coming from a keyboard or a mouse.
(Are a browser’s heuristics perfect at determining the input? That depends. Things get murky once we start factoring in things like touch interactions.)
That means, we get to remove the default focus ring (yay!) for the right types of interactions (double yay!) and display our own custom styles while we’re at it (triple yay!). Allow me to pluck Andy Adams’ fine example straight from our almanac. Note that :focus-visible
cannot remove the focus ring like :focus
can, so the two are used together:
.next-image-button:focus {
outline: none;
}
.next-image-button:focus-visible {
outline: 3px solid blanchedalmond; /* That'll show 'em */
}
Chrome implemented :focus-visible
back in 2018. Firefox had it’s own prefixed version, :-moz-focusring
, prior to this implementation. Safari? Go vote for the feature!
Igalia is gathering funding and working on getting it into Safari! Here’s Brian Kardell on this.
Is there any advantage to work with the :not() selector, like:
a:focus { outline:1px dotted grey; outline-offset:1px; }
a:focus:not(:focus-visible) { outline: none; }
Could that be more compatible for browsers not supporting :focus-visible than removing the outline on :focus?
This is how I would do it, as well. Plus, if you try to combine the focus-visible declaration with something else, such as
a:hover, a:focus-visible{
it will break both declarations if the browser doesn’t support focus-visible. Using regular focus and then a second statement to remove it in certain situations as you’ve described is safer IMO.Love it!
In the short term yes, it’s helpful to use focus:not(:focus-visible).
But as part of this update browsers are also changing the UA stylesheet to use :focus-visible for default focus styles (that’s what Firefox has done and a patch has recently landed in Chromium to do the same).
That means eventually you can just do:
.next-image-button:focus-visible {
outline: 3px solid blanchedalmond;
}
You wouldn’t even need to bother with :focus
As one of folks who worked with others on this proposal, I’m very pleased that you like it! My company, Igalia, works on all of the browser engines and we are even currently working on this in WebKit. More interestingly, I think, is that this work was chosen by developers as part of a collaboration we’re doing with Open Collective called Open Prioritization. In this case, you can do more than just vote on the issue, you can you can help us reach our funding goal to support this and more efforts like it via .
If you want to read more about the current work and links to more about the larger effor, you can also find that in a recent report by the developer working on it
But why the strange naming? “focus visible”
Or am I missing something (non native english)?
If you the read the intent of the a11y requirement for focus state instead of its technical requirements, you’ll find that you should have a clearly defined focused state for all users. The requirement mentions people with cognitive disabilities who probably use a mouse and keyboard and might forget what they just clicked on.
I think the solution we really need is to have more interesting focus state designs to choose from.
when programmatically controlling focus with js, would focus visible be supported or would normal focus outline styles apply until a user hits tab, etc.?
Sadly, it is not supported. At least for me, it would make sense that focus-visible styles appear when using element.focus(), but it doesn’t work that way.
Hey thanks, I hate it. Now tons of sites have these ugly rings around random site elements, distracting my focus. I’m glad this has been developed for those that can benefit from it, but as someone who (like most people) doesn’t need it for accessibility, it’s actively detracting from the online experience for me.
Why not make it easy to turn off for people who don’t need it? Why have it on by default when it’s only useful for a niche selection of users? Accessibility features should absolutely be made available, but there’s no reason they should be forced into the browsers of those that don’t need them. Maybe make an accessibility tab in the settings where people can easily turn this sort of thing on and off depending on their needs and preferences, or have it be a toggle that can be set during installation, but don’t just add it indiscriminately.