Focus Indicators: The Two-Pixel Line Between Usable and Unusable
Tab through a site with a keyboard and watch the focus indicator. If you cannot see where you are, the site fails WCAG 2.4.7, and the cause is usually one line in a CSS reset: outline none. The fix is two lines, and it is the difference between a site a keyboard user can operate and one they cannot.
What the criterion asks
Success Criterion 2.4.7, Focus Visible, is Level AA. Any keyboard-operable user interface must have a mode of operation where the keyboard focus indicator is visible. The browser's default outline satisfies it. A custom focus style satisfies it, provided it is actually visible against the background. What fails it is removing the outline and replacing it with nothing, which is what a CSS reset that sets outline none on :focus does on every element at once.
The Level AAA criterion, 2.4.13 Focus Appearance, is stricter and worth knowing even for AA teams, because it is where the practice is heading. It requires the focus indicator to have an area at least twice the perimeter of the control, and a contrast ratio of at least 3 to 1 against adjacent colors. A two-pixel solid outline in a contrasting color usually meets it. A one-pixel dotted line in a color close to the background does not.
There is a related criterion that teams confuse with this one. Success Criterion 2.4.11, Focus Not Obscured (Minimum), added in WCAG 2.2, requires that a focused element is not entirely hidden by a sticky header, a cookie banner, or a chat widget. A visible focus indicator that slides underneath a sticky header fails 2.4.11, not 2.4.7, and the fix is a scroll offset rather than a thicker outline.
The patterns that break it
The CSS reset is the first. A global :focus { outline: none } was once a common way to remove the outline designers disliked, and it is still sitting in older themes. The replacement that keeps both sides happy is :focus-visible, which shows the outline for keyboard focus and hides it for mouse clicks. Browsers apply :focus-visible by default now, so the cleanest fix is often to delete the reset line entirely and let the browser do its job. Related reading: Accessible Loyalty Points and Rewards Dashboards.
The second pattern is the low-contrast custom indicator. A light blue outline on a white background, or an outline in the brand color at 2 to 1, is technically present and practically invisible. Measure it against the background the same way you measure text contrast, and aim for 3 to 1 or better. A dark outline with a light offset, or a double outline, reads clearly on any background.
The third is the disappearing indicator on custom components. A dropdown built from divs, a tab list, a carousel: if the component manages focus itself and never styles the focused state, keyboard users navigate blind inside it. The component needs a focus style on every focusable part, including the parts that only exist after the component opens.
How to test it
Tab through the site and watch. Every control you reach should show an indicator you can see without hunting for it. Then test with the cookie banner and the chat widget open, because that is the state real users are in, and a focused link under a sticky header is a failure under 2.4.11. Then test on a mobile viewport, where focus indicators are often thinner and the sticky header is taller. More on this: Making Your Shopify Cart Drawer Keyboard Accessible.
Frequently asked questions
Is the browser default outline enough?
Usually yes for 2.4.7. The default outline is visible and meets the AA requirement. The AAA criterion 2.4.13 wants a larger, higher-contrast indicator, which the default does not always provide.
Can I style focus to match my brand?
Yes. Any visible indicator with enough contrast satisfies 2.4.7. A brand-colored outline at 3 to 1 against the background is fine, and a double outline reads clearly on any surface.
Why does focus disappear when I click with a mouse?
Browsers suppress the focus outline on mouse clicks through :focus-visible, because mouse users can see where they clicked. Keyboard focus still shows the outline, which is the behavior the criterion requires.
Does focus need to be visible on every element, or only links and buttons?
Every keyboard-operable control: links, buttons, form fields, custom widgets, anything the Tab key can reach. If it can receive focus, the focus must be visible.