CSS :focus-visible vs :focus - Keyboard-Only Focus Rings

Understand the practical difference between :focus and :focus-visible. Suppress focus rings for mouse clicks while preserving accessibility for keyboard and AT users.

UI State

Detailed Explanation

What's Actually Different

:focus matches whenever an element has DOM focus, regardless of how that focus arrived — keyboard, mouse, touch, or scripted element.focus(). :focus-visible defers to the user agent's heuristic for whether a visible indicator should be drawn. In practice that means:

Interaction :focus :focus-visible
Tab key yes yes
Click on a button yes no
Click on a text input yes yes
element.focus() after a key event yes yes
element.focus() after a click yes no

The intent: keep the ring for keyboard and assistive-tech users, hide it for pointer users who don't need it.

Recommended Pattern

/* Universal default — always polite */
:focus { outline: none; }

/* Keyboard-only ring */
:focus-visible {
  outline: 2px solid Highlight;
  outline-offset: 2px;
}

Using Highlight (a system color keyword) automatically respects the user's OS theme and high-contrast settings.

Don't Suppress Focus Without :focus-visible

The classic anti-pattern is *:focus { outline: none } with nothing to replace it. That makes the page literally unusable for keyboard users, which is a WCAG 2.1 SC 2.4.7 failure.

Inputs Are an Exception

Form fields like <input type="text"> and <textarea> always show :focus-visible — even on click — because typing requires knowing where the caret is. This is intentional UA behavior; don't fight it.

Browser Support

Chrome 86+, Firefox 85+, Safari 15.4+. The behavior was actually built into Chrome much earlier behind a flag, and Safari shipped it last. Any user on a modern browser today gets it.

Use Case

Apply the :focus / :focus-visible split on every interactive component: buttons, links, custom toggles, dropdown items, and tab triggers. It's the single best change you can make to satisfy designers (no orange ring after every click) without hurting keyboard accessibility.

Try It — CSS Selector Reference

Open full tool