Motion & texture
Focus Ring / Focus Indicator
The outline that shows where keyboard focus is—the mouse pointer for keyboard users.
Also known as focus outline · keyboard focus · focus-visible
Demo · not production-ready code
Prompt for AI
Pick a stack, copy a ready prompt, paste into Cursor / Claude / ChatGPT.
Your stack
Shapes the prompt you copy
React + Tailwind + shadcn/ui · EN
Stack: React + Tailwind + shadcn/ui. Use React with Tailwind CSS and shadcn/ui patterns (Radix-based primitives, cn(), class-first styling).
Task: implement "Focus Ring / Focus Indicator".
Never use outline: none without a replacement. Style :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px } so keyboard users see it and mouse clicks usually do not. Prefer outline over border/box-shadow for layout stability. Meet at least 3:1 contrast against the adjacent background (WCAG 2.2).
Anatomy:
- outline: Prefer outline over border—outline does not shift layout.
- outline-offset: A gap between the control and the ring; critical on dark surfaces.
- :focus-visible: Shows for keyboard-style focus, not every mouse click.
Preferred API / pattern: `ring utilities on focus-visible / Radix focus styles`
Keep scope minimal: only this UI pattern, match existing project style.Acceptance checks
- ○Avoid: Global *
- ○Avoid: Border as the focus ring
- ○Avoid: Dark ring on dark background
- ○Avoid: Using
- ○Avoid: Custom control that cannot receive focus at all
In plain wordsHow people search for it
“the blue box that appears around a button when I Tab to it”“the highlight outline when I click into a text field”“that “ugly blue ring” developers keep deleting”
AnatomyOpen for part names
- outline
- Prefer outline over border—outline does not shift layout.
- outline-offset
- A gap between the control and the ring; critical on dark surfaces.
- :focus-visible
- Shows for keyboard-style focus, not every mouse click.
How to write itOpen for stack patterns
Web (HTML/CSS)
:focus-visible { outline: 2px solid }React + Tailwind + shadcn/ui
ring utilities on focus-visible / Radix focus stylesSwiftUI
focusable + focusEffect / default focus ringAnt Design
theme tokens lineWidthFocus / controlOutlineNotes
The most deleted UI element on the web. outline: none without a replacement is an accessibility felony—keyboard users lose their cursor. :focus-visible ended the old trade-off (mouse click also showed a blue box). Redesign the ring; don’t remove it. WCAG 2.2 sets contrast and size floors for focus indicators.
Common mistakesHumans and models trip here
- Global *:focus { outline: none }: the whole site becomes unusable for keyboard users.
- Border as the focus ring: element size jumps—use outline.
- Dark ring on dark background: no contrast equals no ring—offset helps.
- Using :focus instead of :focus-visible: mouse clicks get the ring, designers demand deletion, then it is gone for everyone.
- Custom control that cannot receive focus at all: fix tabindex and semantics first.
More failure symptoms on AI broke it.
Related patterns
Spotted a wrong name or missing pattern?