Skip to main content

Search rules

Search all UI Guides rules by name, category, or source

interactionsTailwind

Use outline-hidden, Not outline-hidden

MUST

MUST: In Tailwind v4, `outline-hidden` sets a real `outline-style: none` and KILLS the focus ring in Windows forced-colors / high-contrast mode, where custom `ring-*` shadows are stripped away — leaving those users with no focus indicator at all. v3's `outline-hidden` emitted an invisible outline that still showed up in forced colors; that behavior was renamed `outline-hidden`. So the ubiquitous `focus:outline-hidden` + custom ring pattern silently regresses on upgrade: use `focus-visible:outline-hidden` PLUS a visible replacement ring. (Distinct from `interactions-clear-focus` — having a ring — and `interactions-focus-ring-shadow` — box-shadow vs outline for radius.)

In v4 outline-hidden really removes the outline and kills the focus ring in forced-colors mode — outline-hidden is the utility that used to be safe

// v4: strips the forced-colors fallback outline
<button class="focus:outline-hidden focus:ring-2 focus:ring-ring" />
// keeps it
<button class="focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring" />

Bad

Good

Why it matters

This is a real accessibility regression introduced purely by a rename. `focus:outline-hidden` + a custom `ring-*` is the single most common focus pattern on the web, and in v3 it was safe: `outline-hidden` did not remove the outline, it emitted a *transparent* one, which Windows forced-colors / high-contrast mode repaints as a visible system outline. In v4 that same class name now sets a literal `outline-style: none`.

Forced-colors mode also overrides your colors and drops `box-shadow`, so the `ring` you replaced the outline with is not there to save you — the user is left with a focused control and no indicator at all, on the exact configuration that most depends on one. Nothing errors, nothing changes in your browser, and the upgrade ships. The fix is the rename Tailwind documents: `focus-visible:outline-hidden` (the old, transparent-outline behaviour) **plus** the visible replacement ring, `focus-visible:ring-2 focus-visible:ring-ring`.

Reserve the new `outline-hidden` for the rare case where you genuinely want no outline in any mode. This is a different rule from `interactions-clear-focus`, which is about having a visible ring at all, and from `interactions-focus-ring-shadow`, which is about drawing that ring with box-shadow so it follows the border radius; both assume the forced-colors fallback you are about to delete here.

Built by Gleb Stroganov, design engineer at Evil Martians.

The rules come from other people's skills and guidelines — Vercel, Rauno Freiberg, @Ibelick, impeccable, Emil Kowalski, Tailwind, RAMS — each one credited on the Sources page. The work here is extraction and wiring: every rule is pulled into one corpus, given a good and a bad example you can operate, a MUST/SHOULD/NEVER rule an agent can paste, and a link back to where it came from.