A focus indicator that survives every background
The one thing a keyboard user depends on entirely — measured against each surface it will actually land on.
A focus indicator that survives every background
The one thing a keyboard user depends on entirely. This measures it against each surface it will actually land on, not just the one in the preview.
2.4.11, 2.4.13, and never removing it
2.4.11 Focus Not Obscured, AA (WCAG 2.2): the focused element must not be entirely hidden by other content — a sticky header covering the thing you just tabbed to fails this.
2.4.13 Focus Appearance, AAA: the indicator must be at least as large as a 2 CSS-pixel perimeter of the element, and reach 3:1 against the colours it replaces.
outline: none with no replacement is the single most damaging line in front-end CSS. It removes the only indication a keyboard user has of where they are. If the default ring is ugly, replace it — do not delete it.
:focus-visible shows the ring for keyboard focus and not for mouse clicks, which is what people usually wanted when they reached for outline: none.
Why a double ring
A single-colour ring has to work on every surface the component can sit on. A dark ring vanishes on a dark background; a light one vanishes on white.
Two concentric rings in opposite tones — a light one inside a dark one, or the reverse — means one of them is always visible. It is what browsers themselves moved to, and it is why the modern Chrome focus ring is two-tone.
Offset matters more than width
A ring drawn tight against the element competes with its border. Two or three pixels of outline-offset separates them and makes the indicator read as a separate thing, which is what it is.