1001Ferramentas
🎯Dev

Focus-Visible CSS Snippet

Builds a ready-to-paste :focus-visible rule from an outline colour and a thickness in pixels, with 2px offset, for the WCAG 2.4.7 focus indicator.

CSS

Removing the ugly outline without blinding keyboard users

The outline a browser draws around the focused element is the main resource for anyone navigating by keyboard: without it, there is no telling where you are. Even so, one of the first things many stylesheets do is erase it with outline none, because it also shows up on mouse clicks, which bothers the design.

The focus-visible pseudo-class settles that standoff. The browser applies it only when it judges the indicator useful — keyboard focus, yes; a mouse click on a button, no. Pick the colour and the thickness and the page assembles the pair of rules: it zeroes the default outline and draws yours under focus-visible, with an offset so the outline does not touch the element edge.

On choosing colour and thickness, WCAG 2.2 adds a new criterion, 2.4.11, asking for at least 3 to 1 contrast between the focus indicator and what was there before, plus a minimum area. Two pixels usually suffice; one pixel in a low-contrast colour goes unnoticed on a light screen. And mind border-radius: an outline on a rounded element follows the curve in current browsers, but comes out rectangular in older ones.

Frequently asked questions

Can I use box-shadow instead of outline?
You can, and it sometimes looks better, but there is a cost: box-shadow disappears in Windows forced high-contrast mode, while outline survives. People using a shadow usually add a transparent outline as well, invisible normally and reappearing in high contrast.
Does focus-visible work in every browser?
In current ones, yes, including Safari since 15.4. For an older browser, the safe pattern is declaring a plain focus rule first and overriding it with focus-visible: whoever does not understand the second keeps an always-visible indicator, which is the milder defect.
What about :focus-within?
That is a different thing: it matches the element containing focus, not the focused element. It serves to highlight a whole card or field when something inside receives focus — useful combined with focus-visible, not a replacement for it.

Related Tools