The Outline That Appears for the Keyboard and Hides for the Mouse
Subtitle: Same ring - only the keyboard sees it.
- Top band - Why the old advice broke the web:
- Click a button, an outline stayed behind
- So stylesheets shipped outline: none
- Mouse users happy, keyboard users lost
- Nothing showed where focus had gone
- Left column - :focus (any focus):
- Matches any focused element
- Ignores how the focus arrived
- A mouse click gets a ring too
- That ring is what people deleted
- Ugly, or unusable - pick one
- Right column - :focus-visible (earned focus):
- Matches only when the browser agrees
- The browser owns the rule, not you
- Click a button: no ring
- Tab to that button: ring
- Keeps the cue where it is needed
- Simple difference:
- :focus = focused, however it happened
- :focus-visible = focused AND ring is warranted
- The heuristic - when the browser shows it:
- Last input was a keyboard
- The element is a text field
- Focus moved programmatically
- No pointer event came first
- Style it right:
- Use outline plus outline-offset
- Outline follows the element shape
- It survives forced-colors mode
- box-shadow does neither
Taped rule strip: You no longer choose between ugly and unusable.
- Honest test - three steps:
- Unplug the mouse
- Tab the whole page
- Check every ring at 3 to 1 contrast
Sticky note - the trap:
A custom ring that fails contrast on its own background is worse than the default it replaced. It looks handled and helps nobody.
Margin note: Text inputs keep a ring on click - a caret is not enough.