vocab.design

accessibility · keyboard · web-platform

Focus visible

also called :focus-visible pseudo-class (css), keyboard-only focus style (community), focus-visible polyfill (community)

A focus style shown only when focus arrived by keyboard or another non-pointer route, so a mouse click does not leave a ring behind.

A focus ring is the style. Focus visible is the rule about when to draw it. Every control that receives focus matches :focus, whether the reader tabbed to it or clicked it, and for years that produced an argument nobody won: keyboard users needed the ring, designers found it noise on a button somebody had just pressed with a mouse, and the truce was usually outline: none, which quietly broke the page for everyone navigating by keyboard.

:focus-visible ends the argument by letting the browser judge how focus arrived. Tab, arrow keys, a screen reader moving the cursor, or a focus() call while the reader was last using the keyboard all count as visible. A mouse press on a button does not. The heuristic is the browser’s, not yours, and it is deliberately generous where guessing would be dangerous: a text input matches :focus-visible even when clicked, because whatever brought focus there, the next thing that happens is typing.

Writing it is two rules and a decision. Style :focus-visible with the ring you want, and if you must suppress the mouse case explicitly, :focus:not(:focus-visible) is the selector that names it. Never remove the outline without replacing it: the accessible minimum is a visible indicator, of adequate contrast and thickness, on every focusable element, and WCAG 2.2 tightened this with Focus Not Obscured and Focus Appearance. If you support older browsers, the historical answer was the WICG polyfill plus a .focus-visible class, or the earlier what-input approach of stamping the current input modality on the document. Both are now legacy: every current engine ships the selector.

One caution: focus is still moving in the pointer case, and it is still real. A control with no visible ring after a click is still the place the next Tab starts from, still where a script’s focus() landed, and still what a screen reader announces. Hiding the indicator is a decision about drawing, never about state, which is why the demonstration below reports focus in both routes and only changes whether the ring is drawn.

Which word?

If you wantsay
showing the ring to keyboard users but not to clickersfocus visible
judging whether a focus ring is strong enoughfocus appearance
marking where keyboard focus is sitting right nowfocus ring

Related

See also: Hover

Sources