UI SKILLBOOK

Skill / Accessibility / Interaction

Accessible Focus States

Keep a visible, high-contrast focus indicator on every interactive element, without a generic browser outline or none at all.

by UI Skillbook

Works with

Claude Code · Codex · Cursor · OpenCode · Universal

Accessible Focus States

outline: none without a replacement is the single most common accessibility regression in hand-built UI. It doesn't just fail an audit — it makes the interface unusable for anyone navigating by keyboard.

When to use

  • Every interactive element: links, buttons, form fields, custom checkboxes/radios, menu items, tabs.
  • Especially custom components built from <div>s that don't get a native focus ring for free.

Principles

  • Focus indication and hover indication are different states with different purposes — don't conflate them. Hover shows "you could click this," focus shows "keyboard input goes here right now."
  • Use :focus-visible instead of :focus so the ring appears for keyboard navigation but not on every mouse click (matches user expectation without visual noise).
  • Focus rings need at least 3:1 contrast against the adjacent background (WCAG 2.2 non-text contrast).

Instructions

  1. Never remove the default outline (outline: none) without providing a replacement that meets contrast requirements.
  2. Style with :focus-visible, and provide a :focus fallback only for browsers that don't support it.
  3. Offset the ring 2px from the element (outline-offset: 2px) so it doesn't get clipped by overflow: hidden containers or blend into the element's own border.
  4. For custom components (div-based dropdowns, custom checkboxes), verify tabindex and ARIA roles are correct before styling focus — a ring on an unfocusable element is meaningless.
  5. Test the full page by tabbing through it with the mouse untouched. Every interactive element must be reachable and visibly focused, in a logical order.

Examples

.control:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

Avoid

  • Don't use box-shadow alone for focus if it can be hidden by neighboring elements' stacking context — verify it's actually visible in context.
  • Don't style focus and hover identically; users need to distinguish "I'm pointing at this" from "this is where my keystrokes go."

References

  • WCAG 2.2 Success Criterion 2.4.11 (Focus Not Obscured) and 1.4.11 (Non-text Contrast).