Focus
One focus style for the whole site, built from two colours so it stays visible on every surface in both themes.
Try it
Tab through these, then switch the theme in the masthead and tab through them again.
Every focusable thing uses the same ring
HTML
<div style="display:flex;gap:var(--p234-space-4);flex-wrap:wrap;align-items:center">
<button class="p234-btn" type="button">Follow this topic</button>
<button class="p234-btn p234-btn--secondary" type="button">Save</button>
<a class="p234-tag" href="#">Visa</a>
<a class="p234-focusable" href="#" style="color:var(--p234-color-link)">An ordinary link</a>
</div>Why it is two colours
The ring is focus amber with focus-outer drawn around it. Neither half clears 3:1 against every background on its own, and that is the point of the pattern rather than a flaw in it:
- On a light page the amber is 1.64:1 on white, which is nowhere near enough. The dark outer ring is what makes it visible.
- On a dark page the outer ring recedes into the background and the amber, now high contrast, carries the indicator alone.
A naive check that demanded 3:1 from the amber on every surface would fail a correct design, and "fixing" it would mean replacing the amber with something muddier. So the build checks the right thing instead: at least one half must clear 3:1 on every surface, in every theme.
export function checkFocus(colors, label) {
for (const bg of FOCUS_SURFACES) {
const inner = contrast(colors["color.focus"], colors[bg]);
const outer = contrast(colors["color.focus-outer"], colors[bg]);
if (Math.max(inner, outer) < 3) { /* fail the build */ }
}
}
This replaced a pair that had been written as "focus against its own ink outer ring", which passed in light and failed in dark at 1.44:1. The rule was wrong, not the colour.
Rules
- Use
:focus-visible, so a mouse click does not leave a ring behind. - Let the ring sit outside the element. It never changes the element's size or shifts the layout.
- Never
outline: nonewithout an equally visible replacement. This is the single most common accessibility regression in a redesign. - Do not give one component its own focus treatment. One ring, site-wide, is how a keyboard user learns to trust it.
Tokens this component reads
--p234-color-focus--p234-color-focus-outer--p234-radius-sm