What Is CSS :focus-visible and How Does It Work?
The :focus-visible CSS pseudo-class is a modern styling
tool that selectively applies focus indicators only when the browser
determines they are helpful to the user, such as during keyboard
navigation. By differentiating between keyboard tabs, mouse clicks, and
touchscreen taps, :focus-visible solves the long-standing
conflict between clean visual design and web accessibility standards,
ensuring critical navigation outlines remain visible to those who need
them without cluttering the interface for mouse users.
The Problem with
the Classic :focus Selector
For years, developers relied on the standard :focus
pseudo-class to style focused interactive elements like buttons, links,
and form fields. However, :focus triggers regardless of
input modality. When a user clicks a button with a mouse, the browser
applies the focus outline just as it would if the user navigated to that
button using the Tab key.
Because these outlines often clashed with visual mockups, designers
and developers frequently removed them using outline: none
or outline: 0. This practice created severe accessibility
barriers:
- Keyboard-only users could no longer see which element currently had focus.
- Screen-magnifier users lost visual tracking cues across the page.
- Navigating complex forms or menus became an exercise in guesswork.
How
:focus-visible Solves the Issue
The :focus-visible pseudo-class uses browser heuristics
to detect how the user is interacting with the page.
- Keyboard Interaction: When a user presses
Tabor uses arrow keys to traverse interactive elements,:focus-visibleactivates and applies the custom focus styles. - Pointer Interaction: When a user clicks a button or interactive element with a mouse, trackpad, or stylus, the browser suppresses the focus ring.
- Form Inputs: Text fields, textareas, and other
editable inputs generally trigger
:focus-visibleeven on mouse click, because text entry always requires clear visual confirmation of the active cursor state.
Implementation and Best Practices
Implementing :focus-visible allows teams to provide
clear, high-contrast outlines for keyboard navigation while keeping
pointer interactions clean.
/* Remove default focus outline only when focus is not visible */
button:focus:not(:focus-visible) {
outline: none;
}
/* Provide a prominent, accessible indicator when visible focus is needed */
button:focus-visible,
a:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}Adopting :focus-visible guarantees compliance with WCAG
2.1 and 2.2 guidelines (specifically Success Criterion 2.4.7: Focus
Visible) without compromising visual aesthetics across different devices
and input methods.