# Focus indicator is visible on all focusable elements; outline not removed without replacement

- **Pattern:** `ab-001598` (`gov-section-508.keyboard-assistive.focus-visible`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001598
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001598)

## Why it matters

Keyboard users must be able to see where focus is at all times—without a visible focus indicator, they are navigating blind. The most common source of this defect is a global `outline: none` reset in CSS, often added to suppress the default browser ring for aesthetic reasons without substituting an equivalent. WCAG 2.2 SC 2.4.7 (Level AA) requires any keyboard operable interface to have a visible focus indicator, and the new SC 2.4.11 (Level AA, added in WCAG 2.2) tightens the minimum indicator specification. Section 508 2018 Refresh 503.3.3 mandates this. Users with motor disabilities who rely on keyboard navigation are most directly harmed, but cognitive disabilities also benefit from persistent focus visibility.

## Severity rationale

High because removing focus indicators makes keyboard navigation effectively unusable without completely preventing it—users can still tab, but cannot see where they are.

## Remediation

Search `src/` for `outline: none` and `outline: 0`. For each occurrence, either remove it or add a replacement `:focus-visible` style with sufficient contrast (3:1 against adjacent colors per WCAG 2.2 SC 2.4.11):
```css
/* In globals.css or your base reset */
*:focus-visible {
  outline: 2px solid #0066cc;
  outline-offset: 2px;
}

/* Custom focus ring for branded elements */
button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px #ffffff, 0 0 0 5px #0066cc;
}
```
Use `:focus-visible` (not `:focus`) so mouse users don't see the ring on click, while keyboard users always do. Verify with WebAIM's contrast checker that the indicator color meets 3:1 against the surrounding background.

## Detection

- **ID:** `focus-visible`
- **Severity:** `high`
- **What to look for:** Inspect CSS for all focusable elements. Check for `outline: none`, `-webkit-appearance: none`, or focus styles that remove the default outline. Verify that every focusable element has a visible focus indicator either via default browser styles or custom CSS.
- **Pass criteria:** All focusable elements have a visible focus indicator (outline, border, background color, or similar). The focus indicator has a contrast ratio of at least 3:1 against adjacent colors.
- **Fail criteria:** Any focusable element has `outline: none` without a replacement focus style, making it impossible to see where focus is located.
- **Skip (N/A) when:** Never — focus visibility is fundamental to keyboard navigation.
- **Detail on fail:** Name the elements and describe the problem. Example: `"Submit button has outline: none in globals.css with no replacement :focus style. Close button in modal has outline: none with only a background-color change on :active, not :focus. Search input has `:focus { outline: none }` and no visible focus indicator."`
- **Remediation:** Always provide a visible focus indicator:
  ```css
  button:focus, input:focus, a:focus {
    outline: 2px solid #0066cc;
    outline-offset: 2px;
  }
  ```
  If you prefer custom focus styles, ensure sufficient contrast:
  ```css
  button:focus {
    border: 2px solid #0066cc;
    box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);
  }
  ```

## External references

- wcag 2.4.7
- wcag 2.4.11
- section-508 503.3.3

Taxons: accessibility

HTML version: https://auditbuffet.com/patterns/ab-001598
