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:

How :focus-visible Solves the Issue

The :focus-visible pseudo-class uses browser heuristics to detect how the user is interacting with the page.

  1. Keyboard Interaction: When a user presses Tab or uses arrow keys to traverse interactive elements, :focus-visible activates and applies the custom focus styles.
  2. Pointer Interaction: When a user clicks a button or interactive element with a mouse, trackpad, or stylus, the browser suppresses the focus ring.
  3. Form Inputs: Text fields, textareas, and other editable inputs generally trigger :focus-visible even 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.