Accessible focus styles without ugly borders

Have you ever heard that you should never remove the focus styles of interactive elements like buttons and links, because of accessibility concerns? You can override them with your own styles, but never remove them. This is because some users rely on these focus indicators to navigate your website. If you remove them completely or make them too subtle, those users will struggle.
At the same time some people complain about the "ugly blue borders" that appear on buttons when they're clicked. This is because buttons get focused both when you navigate to them via keyboard and when you click on them with a mouse or tap them on your phone.
There is a simple solution to both problems: :focus-visible
.
What is focus-visible?
Focus-visible takes both of these wishes into account by hiding the focus styles when they're not necessary. For example:
- if you clicked on a button with a mouse it's very unlikely that you need the focus border to know where you clicked, so the focus styles will be hidden.
- if you navigate using the tab key on your keyboard you might not know where the next focusable element is, so the focus outline will show.
In most cases, users who complain about the blue borders are mouse or touch screen users, so focus-visible
ensures they won't be bothered. Meanwhile, users who rely on focus indicators can still use them. It's a win-win.
How does it work?
The browser decides when focus-visible
styles should show based on factors such as:
- Browser settings.
- The type of element.
- If a mouse, keyboard, or touch screen was used.
Keep in mind that in some cases you might still have the outline even when using a mouse - that's intentional and the decision of the browser.
How do you implement focus-visible?
Simply replace all of your :focus
with :focus-visible
. That will show focus styles only when needed. Example:
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid blue;
}
By using focus-visible your website can be both visually pleasing and accessible to all users.