QuestionsAccessibility

Visible focus indicators & :focus-visible

Focus IndicatorsEasyAccessibility

Why is `outline: none` a bug? What does :focus-visible solve?

What it tests

That the focus ring is a required affordance, and how to satisfy both mouse and keyboard users.

Approach & answer

The focus ring is how a keyboard user knows where they are — remove it and the page becomes unusable without a mouse, which is why a bare `*:focus { outline: none }` is one of the most common and most damaging accessibility bugs (and a WCAG 2.4.7 failure). It's usually done because the default outline looks ugly on mouse click. :focus-visible resolves the tension: the browser applies it only when focus arrives via keyboard (or other non-pointer means) using a heuristic, so you can show a strong ring for keyboard users and suppress it on mouse click. The correct pattern is never to kill the outline outright, but to REPLACE it with a clearly visible custom indicator scoped to :focus-visible. The indicator must meet contrast requirements against the background (WCAG 2.4.11 in 2.2 sets a non-text contrast bar and a minimum area), so a faint 1px light-grey line isn't enough. If you must support older browsers, keep :focus as a fallback and layer :focus-visible on top. Related: never rely on focus styles alone to convey selected/active state to screen-reader users — that's what aria-current, aria-selected, and roles are for; focus-visible is a purely visual affordance.

Use this technique when

Any time a designer wants to hide the focus ring; giving keyboard users a visible, high-contrast indicator.

Code

<style>
  /* WRONG: strips the ring for everyone, keyboard users included */
  button:focus { outline: none; }

  /* RIGHT: strong ring only when focus came from the keyboard */
  button:focus-visible {
    outline: 3px solid #2563eb;
    outline-offset: 2px;
  }
  /* Fallback for browsers without :focus-visible */
  button:focus { outline: 3px solid #2563eb; }
  button:focus:not(:focus-visible) { outline: none; }
</style>
<button>Save</button>

References