Yeda AI Tips · #110

Español

outline: none Without a Replacement Focus Style

One line of CSS is quietly locking keyboard users out of your app. outline: none with no replacement removes the browser's focus ring — the only visual signal a keyboard user has for "you are here." On a login or checkout flow, that isn't a cosmetic bug; it's a locked door.

Why the focus ring exists

Every interactive element — links, buttons, inputs — gets a default focus outline from the browser. Sighted keyboard users (power users, people with motor impairments, anyone whose trackpad died) tab through the page and rely on that ring to know which element will receive their next keypress. Remove it and the page still works, but invisibly: focus moves, nothing on screen changes, and the user is navigating blind.

MDN's documentation for the outline property is blunt about it: if the default focus style is removed, the element must get an obvious replacement. WCAG codifies the same rule as success criterion 2.4.7 Focus Visible (Level AA): any keyboard-operable interface needs a mode where the keyboard focus indicator is visible.

This is not a niche problem. WebAIM's 2026 analysis of the top one million home pages found detectable WCAG failures on 95.9% of them — an average of 56 errors per page. Invisible focus is one of the classic contributors, and it usually enters the codebase as a single well-meaning "reset."

Why teams delete it in the first place

Designers see the ring flash when users click a button and call it ugly. That's because :focus matches on every focus event — mouse, touch, and keyboard alike. The old fix was outline: none, which "solved" the mouse case by breaking the keyboard case.

The modern fix: :focus-visible

:focus-visible matches only when the browser decides the user actually needs to see focus — in practice: yes for keyboard navigation, no for mouse clicks on most controls. It has been Baseline widely available across browsers since March 2022. That means you can have both outcomes at once:

/* 1. Quiet the ring for pointer clicks */
:focus:not(:focus-visible) {
  outline: none;
}

/* 2. Give keyboard users a real indicator */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

currentColor keeps the ring on-brand automatically (it inherits the element's text color), outline-offset adds breathing room so the ring doesn't hug the border, and outlines cost nothing in layout — they take up no space and even follow border-radius in modern browsers.

Rules of thumb

SituationDo this
Ring flashes on mouse clickStyle :focus-visible, not :focus
Legacy outline: none in the codebaseGrep for it; pair every one with a :focus-visible rule
Custom focus style≥2px, high contrast vs. background, outline-offset: 2px
Text inputsKeep a visible indicator on :focus too — browsers show it for pointer focus there by design
Very old browsers@supports not selector(:focus-visible) fallback that styles :focus

Power-user moves

Resources

Building an AI feature? Yeda AI designs, audits, and ships production LLM systems.

Talk to us · Read the blog