Overview
Custom focus indicators pair a non-color signal (outline, underline, glow ring) with a color signal so focus stays legible in any contrast mode, including forced-colors and high-contrast OS modes. Three pairings ship: solid ring on a form CTA, underline + color on an inline link, soft glow on a pill subscribe button.
When to use it
Reach for custom focus indicators when your default browser focus ring clashes visually with the design system. Skip custom indicators on critical UI without keeping the original contrast envelope — tinted glows that disappear on dark themes break keyboard nav. Always pair a custom indicator with :focus-visible so mouse users do not see it on every click.
How it works
The pattern leans on :focus-visible — the browser’s own heuristic for “was this focus reached via keyboard or assistive tech” — so the indicator only renders when it actually helps. For each variant: the ring uses outline (not box-shadow) so it survives forced-colors mode where box-shadow gets stripped. The underline variant draws via a ::after with transform-origin: left + a transition; the glow uses a layered outline + box-shadow stack so the box-shadow handles the soft halo while the outline guarantees a forced-colors fallback.
Production gotchas
Stripping the default focus ring with outline: none without replacing it is the single most common accessibility regression on modern sites. Always pair the strip with a :focus-visible custom indicator. In forced-colors mode every author color is replaced with system colors, so any indicator that depended on a specific hex value disappears — use currentColor or system color keywords (CanvasText, Highlight) for the forced-colors branch. Test with a real screen reader, not just keyboard tabbing, because some readers move a virtual cursor without triggering :focus-visible.
Accessibility
WCAG 2.2 introduces Focus Appearance (2.4.13) which raises the bar beyond 2.4.7: the indicator must have an area at least equal to a 2px border around the bounding box and a contrast ratio of at least 3:1 against adjacent colors. Verify both the focus indicator color and the surrounding focused element color against each background. Under prefers-reduced-motion: reduce skip any transition on the indicator — jump straight to the focused state so the indicator never animates in.
References
Implementation depth
Custom focus indicators must improve the default outline, not erase it. Use focus-visible, outline-offset, or box-shadow rings while preserving a clear keyboard-only affordance.
Forced-colors mode is the deciding test. Decorative shadows may disappear, so provide an outline-based fallback and keep spacing stable so the focus ring does not push layout around controls.