CSS :focus-visible Pseudo-class
The :focus-visible pseudo-class applies while an element matches the :focus pseudo-class and the user agent (browser) determines via heuristics that the focus should be made evident on the element.
1. The Problem with :focus
Traditionally, the :focus pseudo-class applies whenever an element receives focus, whether by keyboard (Tab key), mouse click, or touch.
This led to a common issue:
- Designers/Developers didn't like the default focus ring appearing when users clicked buttons with a mouse.
- They removed it using
outline: none. - Result: Keyboard users (who rely on the focus ring to know where they are) could no longer navigate the site effectively. This is a major accessibility failure.
2. The Solution: :focus-visible
:focus-visible solves this by letting the browser decide when to show the focus indicator.
- Keyboard Navigation: If a user tabs to a button,
:focus-visiblematches (ring shown). - Mouse Click: If a user clicks a button,
:focus-visibleusually does not match (no ring shown), even though:focusdoes. - Text Inputs: Text inputs usually always match
:focus-visiblebecause the user needs to see the cursor/focus regardless of input method.
3. Basic Usage
The best practice is to remove the default outline only when :focus is active but :focus-visible is not, or simply define styles specifically for :focus-visible.
/* Default focus style (often reset by browsers/frameworks) */
:focus {
outline: 2px solid blue;
}
/*
Modern approach:
Define styles specifically for focus-visible.
Browsers often default to this behavior now.
*/
button:focus-visible {
outline: 2px solid blue;
outline-offset: 2px;
}
button:focus:not(:focus-visible) {
outline: none;
}
4. Browser Heuristics
The browser uses heuristics to determine if focus should be visible. Generally:
- True: If the user interacts via keyboard (Tab, Arrow keys).
- True: If the element is an
<input>,<textarea>, orcontenteditable="true"(regardless of input device). - False: If the user interacts via mouse or touch on non-text elements (buttons, links).
programming/css/css programming/css/pseudo-classes-and-pseudo-elements programming/css/selectors