Selector pseudo-class :focus-visible

The :focus-visible pseudo-class applies while an
element matches the :focus pseudo-class

The :focus pseudo-class always matches the currently-focused element. The :focus-visible pseudo-class also matches the focused element, but only if the user needs to be informed where the focus currently is.

When the :focus pseudo-class is used, it always targets the currently focused element. This means that when a user employs a pointing device, a visible focus ring appears around the focused element, which some consider obtrusive. The :focus-visible pseudo-class respects user agents’ selective focus indication behavior while still allowing focus indicator customization.

.focus-only:focus {
  outline: 2px solid black;
}

.focus-visible-only:focus-visible {
  outline: 4px dashed darkorange;
}

Providing a :focus fallback

.button:focus-visible {
  /* Draw the focus when :focus-visible is supported */
  outline: 3px solid deepskyblue;
  outline-offset: 3px;
}

@supports not selector(:focus-visible) {
  .button.with-fallback:focus {
    /* Fallback for browsers without :focus-visible support */
    outline: 3px solid deepskyblue;
    outline-offset: 3px;
  }
}

:focus vs :focus-visible

:focus

Triggers on:

Problem: you get focus styles even when clicking with a mouse (often unwanted).

:focus-visible

Triggers only when the browser thinks focus should be visible, typically:

This is exactly what users expect.

&:focus-visible {
  background-color: transparent; // Prevents hover/active styles from interfering with focus
  outline: 2px solid var(--color-blue);
  outline-offset: -1px;
}