:focus matches the focused element. :focus-visible matches it when the browser’s heuristics indicate that a visible focus indicator should be shown.

That is more precise than saying it means “keyboard focus only.” A text input can need a visible indicator even when someone clicks it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/* A visible fallback, including browsers without :focus-visible. */
a:focus, button:focus, input:focus {
  outline: 2px solid #58a6ff;
  outline-offset: 4px;
}

@supports selector(:focus-visible) {
  a:focus:not(:focus-visible),
  button:focus:not(:focus-visible) {
    outline: none;
  }
}

The example keeps input focus visible and only removes the link/button outline when the browser says the indicator is unnecessary. Adjust the colour for the actual surface; a colour that works on a dark background may be too faint on a light one.

After styling, move through the page with Tab and Shift+Tab. Check links, icon buttons and inputs, including elements inside clipped or scrolling containers. A correct selector does not help if the outline is hidden behind another element.

Reference: MDN on :focus-visible.