SayUI
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 itthe highlight outline when I click into a text fieldthat “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/uiring utilities on focus-visible / Radix focus styles
SwiftUIfocusable + focusEffect / default focus ring
Ant Designtheme tokens lineWidthFocus / controlOutline

Notes

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?

Message on X