A single brand-blue outline can look tidy in a component library and still disappear on a dark card, pale panel, gradient hero or image tile. That is why I treat two color focus indicator CSS as a practical default for interfaces with mixed surfaces, not as a decorative flourish.
The core idea is simple: pair a light ring band with a dark ring band, test the pair, then test the actual component context. W3C Technique C40 says that when the two indicator colors have at least a 9:1 contrast ratio with each other, at least one is guaranteed to reach 3:1 contrast against any single solid background, as long as the whole indicator sits on that one solid color. That makes a two-color ring a strong baseline for keyboard focus visibility, but images, gradients and overlapping UI still need direct checking.
Table of Contents

Why two color focus indicator CSS works on solid surfaces
W3C Technique C40, updated 12 January 2026, describes a two-color focus indicator built from a light and dark band. Its useful rule is mathematical rather than stylistic: if the two ring colors contrast with each other at 9:1 or higher, at least one ring color will contrast at 3:1 against any one solid background color.
In practice, a pair like #FFFFFF and #111827 is easy to reason about after you verify the contrast. A brand-friendly pair can also work, but do not assume it works because it looks bold in a design file. Start by checking the two ring colors against each other in Compare Colors or the Contrast Checker.
This technique is informative guidance, not the only valid way to satisfy WCAG. I use it because it gives designers and front-end developers a repeatable starting point before component-by-component testing begins.
Try this palette: #FFFFFF #111827 #2563EB #F3F4F6

Translate WCAG contrast language into a focus-ring workflow
WCAG 2.2 is a W3C Recommendation dated 12 December 2024, with the change log noting original WCAG 2.2 publication on 05 October 2023. For custom focus styles, three success criteria matter in day-to-day color decisions.
- Focus Visible, SC 2.4.7, Level AA: keyboard focus must be visibly indicated.
- Non-text Contrast, SC 1.4.11, Level AA: the visual information required to identify UI components and states needs at least 3:1 contrast against adjacent colors, with the WCAG exceptions for inactive or unmodified user-agent components.
- Focus Appearance, SC 2.4.13, Level AAA: the visible focus indicator has an area at least as large as a 2 CSS pixel thick perimeter of the unfocused component, and at least 3:1 contrast between the same pixels in focused and unfocused states.
The Understanding Focus Appearance page, updated 10 August 2026, makes the relationship practical: focus indicators communicate state, so they relate to both Focus Appearance and Non-text Contrast. I test two things separately. First, does the focused state visibly change from the unfocused state? Second, does the ring contrast with the colors touching it?
Use the Focus Indicator Contrast Checker to test the focused/unfocused state change, adjacent background contrast and ring width together.
Try this palette: #0F172A #FFFFFF #F59E0B #E0F2FE

Where two color focus indicator CSS stops being automatic
The C40 guarantee applies only when the entire indicator is drawn over one solid background color. That sentence matters. A photo card, mesh gradient, video thumbnail, frosted panel, shadowed card edge or clipped container can put different pixels behind different parts of the same ring.
For mixed backgrounds, pick representative worst-case swatches and test them instead of relying on the 9:1 pair alone. A pale ring can disappear over a bright part of a photograph while the dark ring still works, or the reverse can happen over a shadow. If the ring straddles a card edge, test the outside page surface and the inside component surface.
I map the risky surfaces first: white cards, dark cards, brand panels, alert tints, gradients, image cards, dark mode, high-contrast themes and disabled-looking states. Then I run ring tokens through the Contrast Grid and broader color systems through the Palette Accessibility Matrix. If an image drives the palette, the Palette From Image tool can help you extract swatches to test.
Try this palette: #0B1120 #F8FAFC #16A34A #DB2777 #7C3AED
Write the CSS without erasing keyboard focus
MDN guidance in the research notes that :focus-visible follows browser logic for when focus should be visibly indicated, especially for keyboard navigation. It also warns that outline: 0 or outline: none removes the browser default focus style, so never remove it unless you replace it with an obvious visible indicator.
Here is a compact two-band pattern. The offset is set to zero so the 2px outline and the visible outer part of the 4px spread shadow act like adjacent bands. The raw hex values are examples for code only, not universal tokens. Test your own values before shipping.
:root {
--focus-ring-inner: #ffffff;
--focus-ring-outer: #111827;
--focus-ring-offset: 0px;
--focus-ring-width: 2px;
}
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
outline: var(--focus-ring-width) solid var(--focus-ring-inner);
outline-offset: var(--focus-ring-offset);
box-shadow: 0 0 0 calc(var(--focus-ring-width) * 2) var(--focus-ring-outer);
}
@supports not selector(:focus-visible) {
:where(a, button, input, select, textarea, [tabindex]):focus {
outline: var(--focus-ring-width) solid var(--focus-ring-inner);
outline-offset: var(--focus-ring-offset);
box-shadow: 0 0 0 calc(var(--focus-ring-width) * 2) var(--focus-ring-outer);
}
}
For layered effects, keep accessibility separate from decoration. The CSS Box Shadow Generator can help you shape the outer band, but a soft decorative shadow is not automatically a valid focus indicator.
Try this palette: #FFFFFF #111827 #3B82F6 #E5E7EB
Turn accessible focus rings into design tokens
A focus ring should not be a one-off rule pasted into each component. Store it as semantic tokens so buttons, links, menu items, cards and form fields stay consistent across themes.
- Base values: keep precise light and dark ring colors, such as #FFFFFF and #111827, after testing.
- Semantic aliases: use names like
--focus-ring-light,--focus-ring-dark,--focus-ring-widthand--focus-ring-offset. - Theme overrides: define exceptions for inverse themes, image cards, compact controls and containers with
overflow: hidden.
The CSS Variable Theme Generator is useful once you have validated values and want to export them into a broader token system. If you need to audit text and icon colors on the same components, pair that work with the Contrast Ratio Checker so focus accessibility is not isolated from overall color accessibility.
Try this palette: #111827 #FFFFFF #10B981 #F97316 #CBD5E1
QA checklist before shipping two color focus indicator CSS
Before release, test the keyboard path, not only the color pair. Tab through every interactive element in source order, including links inside cards, icon buttons, menus, form controls, dialogs and skipped or hidden states. A ring that passes contrast but gets clipped by a parent container still fails the person trying to use it.
- Check focused and unfocused state contrast for the component.
- Check ring contrast against adjacent page and component colors.
- Repeat in light mode, dark mode, brand panels, alert surfaces, gradients and image cards.
- Look for clipping caused by
overflow: hidden, tight containers or negative margins. - Keep browser or user-agent focus behavior intact when possible, especially for users who rely on system preferences.
Custom focus styles are responsible for meeting the contrast expectation. Unmodified browser default focus indicators can be treated differently under the guidance, but once you style the indicator yourself, test it like any other critical UI state.
Try this palette: #020617 #F8FAFC #22C55E #EF4444 #60A5FA
Frequently asked questions
What is a two-color focus ring?
A two-color focus ring uses two visible bands, usually one light and one dark, around a focused component. The goal is to keep at least one band visible when the component appears on different solid backgrounds.
Why does W3C Technique C40 mention a 9:1 contrast ratio?
Technique C40 says that if the two indicator colors contrast with each other at 9:1 or higher, at least one of those colors is guaranteed to reach 3:1 contrast against any single solid background behind the whole indicator.
Does a two-color ring automatically pass on images and gradients?
No. The C40 guarantee applies to one solid background behind the whole ring. Images, gradients, glass effects, video thumbnails and overlapping surfaces need direct testing against the actual or representative adjacent pixels.
Should I use :focus or :focus-visible?
Use :focus-visible for the primary custom style because it follows browser logic for when visible focus is expected, especially keyboard navigation. Add a :focus fallback inside @supports not selector(:focus-visible) if you need older-browser support.
Is WCAG 2.4.13 required for every WCAG AA project?
WCAG 2.4.13 Focus Appearance is Level AAA in WCAG 2.2. WCAG 1.4.11 Non-text Contrast is Level AA. Do not treat the full Level AAA focus appearance area requirement as mandatory for AA unless the project has adopted it.
Can I remove the browser outline?
Only remove or override the default outline if you provide a clearly visible replacement. Setting outline: none without a tested alternative can leave keyboard users without a usable focus indicator.
What focus-ring width should I start with?
A practical starting point is a 2 CSS pixel inner band plus a visible 2 CSS pixel outer band. Test the actual component because size, offset, adjacent colors and clipping all affect whether the indicator is usable.
Next steps
Two color focus indicator CSS gives you a resilient starting point for mixed interfaces because a strongly contrasting light and dark pair can cover many solid backgrounds. The important word is starting. WCAG-related focus testing still depends on the component, the adjacent colors, the focus-state change and the surface behind the ring.
My recommended workflow is simple: inventory surfaces, choose a light and dark focus pair, verify the pair, implement with :focus-visible, test real components, then store the result as design tokens. That keeps accessible focus rings visible where they matter most: in the actual product, under the user’s keyboard.
For standards context, I would keep W3C Technique C40, Understanding Non-text Contrast, Understanding Focus Appearance and the WCAG Recommendation close to the implementation notes.
Related tools & resources on 66Colorful:
- Focus Indicator Checker
- Compare Colors
- Contrast Grid
- Palette Accessibility Matrix
- Designing For Color Blindness