Skip to content

Tutorial

How to build a visible focus indicator

In short

Never remove the focus ring without a replacement. Use :focus-visible to show keyboard users a clear ring without it appearing on every mouse click. The indicator needs at least 3:1 contrast against its surroundings; outline-offset gives it visible separation.

At a glance

  1. Remove outline: none

    Search your CSS for outline: none or outline: 0 and replace it with a real indicator.

  2. Use :focus-visible

    Style the ring via :focus-visible so it shows on keyboard focus but not on mouse click.

  3. Ensure contrast

    Choose a ring colour with at least 3:1 against the surroundings (1.4.11).

  4. Add offset

    Set outline-offset so the ring does not merge with the element's edge.

Anyone operating the page with a keyboard must always see where focus currently is. That is exactly what outline: none removes. It is arguably the most harmful one-liner in many stylesheets, often added because the default ring is seen as ugly. The fix is not removal, it is replacement.

The problem

Before: not accessibleCSS
/* Entfernt den Fokus-Ring komplett -> Tastaturnutzer sind verloren */
*:focus {
  outline: none;
}

button:focus {
  outline: 0;
}

With no visible focus, a user tabs through the page blind: they cannot tell which button or link is active. That fails 2.4.7 (Focus Visible).

The fix: :focus-visible plus contrast

:focus-visible shows the ring only when the browser detects keyboard interaction, not on every mouse click. You get the tidy look designers want without abandoning keyboard users.

After: accessibleCSS
/* Kein Ring bei Maus-Klick, klarer Ring bei Tastatur-Fokus */
:focus-visible {
  outline: 3px solid #1d4ed8;   /* >= 3:1 zur Umgebung (1.4.11) */
  outline-offset: 2px;          /* Abstand, damit der Ring nicht im Element verschwindet */
  border-radius: 2px;
}

/* Fallback fuer aeltere Browser ohne :focus-visible:
   Ring zeigen, aber wieder ausblenden, sobald :focus-visible unterstuetzt wird */
:focus {
  outline: 3px solid #1d4ed8;
  outline-offset: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}
  • Contrast: the ring needs at least 3:1 against the adjacent colour (1.4.11). Blue (#1d4ed8) on white meets that.
  • Thickness and offset: at least 2px thickness plus outline-offset keeps the ring perceivable on coloured surfaces too.
  • Do not obscure: sticky headers or cookie banners must not cover the focused element (2.4.11 Focus Not Obscured, WCAG 2.2).

Test

  1. Click nowhere, press only Tab: every stop must show a clearly visible ring.
  2. Check interactive elements on coloured backgrounds: the ring must stay visible there too.
  3. Scroll with a sticky header open: the focused element must not disappear behind it.

Frequently asked questions

Why :focus-visible instead of :focus?
:focus would show the ring on every mouse click too, which annoys many designers and leads to the harmful outline: none. :focus-visible shows the ring only on keyboard interaction and resolves the conflict.
Is a colour change enough as a focus indicator?
Only if the change is large and high-contrast enough. A pure colour change often fails 1.4.1 (colour alone) or the 3:1 contrast. An outline ring is the safer choice.
Can I adapt the ring to rounded corners?
Yes, outline follows border-radius automatically. With outline-offset you can also control the spacing.

Request a free scan

Tell us your domain — we run a free initial scan and show you the most important barriers.