Level AAA

Default browser focus rings are typically 1-2px and often fall below the 3:1 focused-vs-unfocused contrast threshold on styled components

2.4.13 Focus Appearance

In Plain Language

2.4.13 Focus Appearance is Level AAA, new in WCAG 2.2. It is the quality-of-indicator criterion. Where 2.4.7 Focus Visible only requires that some focus indicator exists, 2.4.13 specifies what that indicator must look like: the changed area must be at least as large as a 2 CSS pixel thick perimeter of the unfocused component, and the pixels that change between the focused and unfocused states must have a contrast ratio of at least 3:1 against themselves[1].

The third clause: the indicator must not be entirely hidden by other content -- the same failure mode 2.4.11 Focus Not Obscured (Minimum) addresses at Level AA[2].

Why It Matters

  • A 1px outline in a color close to the component border can technically satisfy 2.4.7 while remaining invisible to a low-vision user at normal viewing distance. 2.4.13 closes that gap by specifying a measurable minimum area and contrast delta[1].
  • The 2 CSS pixel perimeter rule is a geometric area test, not a stroke-width test. A box-shadow glow or a background-color swap counts only if the total changed area equals or exceeds the perimeter of a 2px-thick ring around the component's bounding box.
  • The 3:1 contrast test compares the same pixel coordinates in the focused vs. unfocused states, not the indicator against its background. A focus ring that swaps #cbd5e1 for #e2e8f0 at the same pixel location fails the ratio even if each color has adequate contrast against the page background.
  • Screen-magnification users navigate by pixel, not by page. A thick, high-contrast outline is the affordance that tells them where Tab landed inside the magnified viewport.

Examples

Do: Thick, high-contrast outline meets size and contrast requirements

Tab through these buttons -- the focus ring is thick and high-contrast:

✔ 3px outline with 2px offset exceeds the 2px perimeter minimum. Outline color (#1a6b5a) has 5.8:1 contrast against white background.

button:focus-visible {
  /* 3px outline exceeds the 2px perimeter minimum */
  outline: 3px solid #1a6b5a;
  outline-offset: 2px;
}

/* Contrast check:
   Focus indicator (#1a6b5a) vs. adjacent white (#fff) = 5.8:1
   Well above the 3:1 minimum */
Don't: Thin, low-contrast indicator fails size and contrast

Tab through these buttons -- the focus ring is barely visible:

✘ 1px outline is below the 2px perimeter minimum. Indicator color (#cbd5e1) has only 1.4:1 contrast against white -- well below the 3:1 requirement.

How to Fix It

  1. Set outline: 2px solid <high-contrast-color> with outline-offset: 2px. A 2px outline meets the perimeter area minimum; the offset pulls the ring clear of the element edge so it does not visually merge with the component border. This is the canonical shape of a compliant indicator.
  2. Never ship outline: none without a replacement. Stripping the UA outline and relying on a border-color swap almost always fails either the area or contrast test. If you remove the outline, attach a :focus-visible rule that reinstates a 2px+ ring.
  3. Test focused vs. unfocused at the same pixel coordinates. Screenshot the component in both states, diff the pixels that change, and verify that diff hits 3:1. This is not the same check as 1.4.11 Non-text Contrast -- 2.4.13 compares a pixel to its own prior value, not to the adjacent background[1].
  4. Background-color swaps alone rarely pass. A subtle fill change fails the perimeter area test unless the fill change is strong enough that the total changed pixel area matches the 2px-perimeter geometry. Pair any fill swap with an outline.
  5. Verify on every surface the component lands on. If the same button appears on a white card and a dark hero, the focused-vs-unfocused pixel delta has to clear 3:1 in both contexts. A single indicator color rarely works for both -- use currentColor or a token that inverts with the surface.
  6. Confirm the indicator is not obscured. Sticky headers, cookie banners, and chat widgets can cover a focused element; 2.4.13's "not entirely hidden" clause overlaps with 2.4.11, and the fix is the same -- use scroll-margin on focusable elements and avoid fixed overlays that cover the viewport edges[2].

References

  1. [1] W3C (2023). Understanding Success Criterion 2.4.13: Focus Appearance. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance.html
  2. [2] W3C (2023). Understanding Success Criterion 2.4.11: Focus Not Obscured (Minimum). W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html