You can browse the Web using a mouse, keyboard and all sorts of assistive technology devices. Whichever input method you use, a clear indication of the current interactive element is crucial for a good user experience and accessibility. Default browsers stylesheets do a great job at it, but sometimes we want to be a little bit more sophisticated, or at least different.
The use case that you might have encountered is when you want to style the focus state of an element, but you don’t want to apply the same style to the focus state of a mouse click. This is where the :focus-visible
pseudo-class comes in handy.
See the following code and example.
&:hover {
background: red;
color: white;
}
&:focus {
outline-color: #007dbc60;
outline-offset: 0.5rem;
transform: scale(1.5);
}
We applied a different outline
color on focus, and at the same time we applied a transform(1.5)
to the element. So that it looks obvious when the element is focused.
That’s where most of us see the problem.
outline
and the element grow bigger with transform
.outline
but the element still grow bigger with transform
. We don’t want that.Somehow when we click, it captures the focus
state as well.
You might wondering why only the scale
is applied, but not the outline
?
The reason is that the outline
is a property that is only visible when the element is focused using focus-visible
under the hood. So when we click, the outline
is not visible, but the scale
is still applied.
:focus-visible
?:focus-visible
is a pseudo-class that matches when an element matches the :focus
pseudo-class and the user agent determines via heuristics that the focus should be made evident on the element. In other words, it matches when an element matches the :focus
pseudo-class, but only if the focus ring or other indicator should be drawn for that element.
To fix the issue above, we can simply change :focus
to :focus-visible
in our CSS.
- &:focus {
+ &:focus-visible {
outline-color: #007dbc60;
outline-offset: 0.5rem;
transform: scale(1.5);
}
The :focus-visible
pseudo-class is supported by all major browsers, except for IE11.
If you want to style the focus state of an element, but you don’t want to apply the same style to the focus state of a mouse click, you can use the :focus-visible
pseudo-class instead of :focus
.