# Clear Focus

**MUST** · **ID:** `interactions-clear-focus` · **Category:** interactions
**Source:** [Vercel](https://github.com/vercel-labs/agent-skills/blob/main/skills/web-design-guidelines/SKILL.md)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/interactions-clear-focus

> MUST: Visible focus rings (`:focus-visible`; group with `:focus-within`)

Every focusable element shows a visible focus ring

Focus indicators are essential for keyboard navigation. Use :focus-visible to show focus rings only during keyboard navigation, not when clicking with a mouse. "Visible" is not a matter of taste — WCAG 2.2 SC 2.4.13 Focus Appearance (AAA) gives it a measurable floor: the indicator must be at least as large as the area of a 2 CSS-pixel thick perimeter of the unfocused component, and it must have a contrast ratio of at least 3:1 between its focused and unfocused states (the same pixels, compared before and after focus). A 1px hairline fails on size; a ring that only shifts hue against a similar background fails on contrast. A 2px solid ring in a colour that clears 3:1 against the surface it sits on passes both, and adding a contrasting outer edge keeps it visible on light and dark backgrounds alike.

## Bad — do not do this

`interactions-clear-focus-bad`

```tsx
export function ClearFocusBad() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <style>{`
        .no-focus-ring:focus,
        .no-focus-ring:focus-visible {
          outline: none;
          box-shadow: none;
        }
      `}</style>
      <div className="rounded-lg border border-border bg-card p-4 shadow-sm">
        <h3 className="text-sm font-medium">Unsaved changes</h3>
        <p className="mt-1 text-xs text-muted-foreground">
          Your edits haven't been saved yet.
        </p>
        <div className="mt-4 flex items-center justify-end gap-2">
          <button className="no-focus-ring rounded-md px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted transition-colors">
            Cancel
          </button>
          <button className="no-focus-ring rounded-md border border-input bg-background px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors">
            Discard
          </button>
          <button className="no-focus-ring rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors">
            Save changes
          </button>
        </div>
      </div>
      <p className="text-xs text-muted-foreground">
        Try tabbing through — no visible focus indicator
      </p>
    </div>
  );
}
```

## Good — do this

`interactions-clear-focus-good`

```tsx
export function ClearFocusGood() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="rounded-lg border border-border bg-card p-4 shadow-sm">
        <h3 className="text-sm font-medium">Unsaved changes</h3>
        <p className="mt-1 text-xs text-muted-foreground">
          Your edits haven't been saved yet.
        </p>
        <div className="mt-4 flex items-center justify-end gap-2">
          <button className="rounded-md px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card transition-colors">
            Cancel
          </button>
          <button className="rounded-md border border-input bg-background px-3 py-1.5 text-sm font-medium hover:bg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card transition-colors">
            Discard
          </button>
          <button className="rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card transition-colors">
            Save changes
          </button>
        </div>
      </div>
      <p className="text-xs text-success">
        Tab through to see clear focus rings (keyboard only)
      </p>
    </div>
  );
}
```

## References

- [:focus-visible pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:focus-visible)
- [WCAG Focus Visible](https://www.w3.org/WAI/WCAG21/Understanding/focus-visible.html)
- [WCAG 2.2 SC 2.4.13 Focus Appearance](https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance.html)
