WCAG 2.4.7: Focus Visible
When someone navigates your page with the keyboard, they must always be able to see which element has focus. This Level AA criterion is what stops keyboard navigation from becoming a blind guess — strip the focus ring and a sighted keyboard user, a switch-device user, and anyone who cannot use a mouse loses all sense of where they are on the page.
The success criterion, in full
Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.
Why a visible focus indicator matters
For anyone who navigates without a mouse — keyboard-only users, people using switch devices or sip-and-puff controls, many people with motor or visual disabilities, and plenty of power users — the focus indicator is the cursor. It is the single piece of feedback that answers "where am I, and what will Enter or Space do right now?" Remove it and the page becomes unusable: pressing Tab moves focus invisibly, and the only way to find a button is to tab blindly and hope.
This is one of the most common and most damaging accessibility failures on the web, and it is almost always self-inflicted: a CSS reset or a designer's dislike of the "ugly" default ring leads someone to write outline: none with nothing to replace it. The fix costs a few lines of CSS, and a strong, on-brand focus style is a usability win for everyone, not just an act of compliance.
What 2.4.7 actually requires
The criterion has a narrow, testable core. Meet these and keyboard navigation stays usable.
1. A visible indicator when an element has keyboard focus
Focus must be shown, not hidden.
Any keyboard-operable user interface has a mode of operation where the keyboard focus indicator is visible. When a user tabs to a link, button, input, or any focusable control, something on screen must change to show exactly where focus now sits — the default browser focus ring, a custom outline, a background change, or another clearly perceivable cue.
2. It applies to every focusable component
Not just links — buttons, inputs, custom widgets, all of them.
The indicator must appear on every component that can receive keyboard focus, including custom controls you have built with tabindex, ARIA widgets like menus and tabs, and form fields. A site that styles focus on links but strips it from buttons or custom components still fails 2.4.7.
3. Visible is the baseline — distinct and strong is the goal
2.4.7 asks for visible; 2.4.11 and 2.4.13 raise the bar.
2.4.7 at Level AA only requires that the indicator is visible. WCAG 2.2 adds 2.4.11 Focus Not Obscured (the focused element must not be hidden behind sticky headers or other content) and 2.4.13 Focus Appearance (AAA, defining minimum size and contrast). Designing a strong indicator now satisfies all three at once.
Note:The phrase "a mode of operation" means the indicator does not have to be visible during a mouse click — it must be visible when the user is operating the interface by keyboard. That is exactly what :focus-visible gives you, which is why it is the modern way to satisfy 2.4.7.
The outline: none trap
By far the most common way to fail 2.4.7 is to remove the default focus outline without putting anything back. It breaks in several ways:
- outline: none (or outline: 0) on a focusable element with no replacement deletes the only cue keyboard users have for where they are — an instant, total failure of 2.4.7.
- A blanket reset like *:focus { outline: none } or :focus { outline: 0 } strips focus from every control on the site at once, including ones you never styled.
- Component libraries and CSS resets (older Normalize/reset stylesheets, some UI kits) sometimes ship outline removal by default — check what your dependencies do, not just your own CSS.
- Setting only a faint colour change (for example a 1px border that barely differs from the resting state) is technically present but practically invisible, and reviewers will treat it as a failure.
If you must remove the default ring for design reasons, the rule is simple: always replace it with an equally or more visible indicator — a custom outline, a box-shadow ring, a thicker border, or a clear background change — and scope it to :focus-visible.
:focus vs :focus-visible
The reason developers reach for outline: none is usually that they dislike seeing a focus ring after a mouse click. The modern fix is the :focus-visible pseudo-class, which lets you keep a strong indicator for keyboard users without it appearing on every click.
:focus
Matches whenever an element is focused — including immediately after a mouse click. Styling :focus alone can leave a ring lingering after a click, which is what tempts people to remove it entirely.
:focus-visible
Matches only when the browser decides a visible indicator is appropriate — in practice, keyboard navigation. This is exactly the "mode of operation" 2.4.7 talks about, and it is now supported in every modern browser.
The practical pattern: keep a sensible :focus fallback for older engines, then layer a strong, on-brand ring on :focus-visible. Never remove the indicator without adding one back.
Code examples
A strong, modern focus style with :focus-visible
The core pattern: a clearly visible ring for keyboard users, kept off the screen during mouse clicks. The outline-offset gives the ring breathing room so it stays visible against the control.
/* A visible, on-brand indicator for keyboard users */
:focus-visible {
outline: 3px solid #1d4ed8; /* >= 3:1 against the background */
outline-offset: 2px; /* lift it off the control */
border-radius: 2px;
}
/* Optional: hide the ring for mouse users only,
while keeping a fallback for browsers without
:focus-visible support. */
:focus:not(:focus-visible) {
outline: none;
}A box-shadow ring that hugs rounded corners
When a control has a border radius, a box-shadow ring follows the curve neatly. Combine it with a transparent outline so the indicator still shows in Windows High Contrast Mode, where box-shadows are dropped.
.button:focus-visible {
/* Visible ring that follows rounded corners */
box-shadow: 0 0 0 3px #fff, 0 0 0 6px #1d4ed8;
/* Transparent outline = a visible ring in forced-colors mode */
outline: 3px solid transparent;
outline-offset: 2px;
}A global, accessible default with Tailwind CSS
If you use a utility framework, set one consistent keyboard focus ring across the whole app rather than removing focus per component.
<!-- Per element: a visible ring only for keyboard focus -->
<button
class="rounded-md bg-blue-700 px-4 py-2 text-white
focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2
focus-visible:outline-blue-900"
>
Save changes
</button>
/* Or set a sensible default once, in your base layer */
@layer base {
:focus-visible {
outline: 3px solid theme(colors.blue.700);
outline-offset: 2px;
}
}Respecting Windows High Contrast / forced colors
In forced-colors mode the operating system overrides your colours. Use the system Highlight colour so the focus ring honours the user's theme.
@media (forced-colors: active) {
:focus-visible {
outline: 3px solid Highlight;
outline-offset: 2px;
}
}Common mistakes
- Writing outline: none (or a global *:focus { outline: 0 }) with nothing to replace it — the single most common cause of a 2.4.7 failure.
- Styling focus only on links while leaving buttons, inputs, or custom widgets with no visible indicator.
- Removing focus from custom controls (divs with tabindex, ARIA menus, tabs) that the browser would never style by default.
- A focus indicator so faint it is effectively invisible — a 1px colour shift that does not clearly stand out from the resting state.
- A focus ring that is hidden behind a sticky header, toolbar, or cookie banner when the element receives focus (also a 2.4.11 failure).
- Relying on a box-shadow ring only, which disappears in Windows High Contrast Mode because forced colors removes shadows.
- Inheriting outline removal from a CSS reset or component library and never checking what the dependency actually does.
- Showing the keyboard ring on mouse clicks too, then deleting it to 'clean it up' instead of scoping the style to :focus-visible.
How to test for 2.4.7
- 1
Tab through the whole page
Put the mouse away and press Tab from the top of the page to the bottom. At every stop — links, buttons, inputs, custom widgets — you must be able to see clearly which element now has focus. If focus ever vanishes, you have a failure.
- 2
Watch for elements that lose the ring
Pay special attention to custom buttons, icon-only controls, dropdowns, tabs, and anything built with divs and tabindex. These are where developers most often strip or forget the indicator.
- 3
Check the indicator against its background
Make sure the focus style stands out from the resting state and the surrounding colours. Aim for a ring around 2px thick with at least 3:1 contrast against adjacent colours to also satisfy the stronger WCAG 2.2 guidance.
- 4
Test sticky and overlay content
Tab to elements near sticky headers, footers, and dialogs. Confirm the focused element is not hidden behind them — that is the related 2.4.11 Focus Not Obscured criterion.
- 5
Verify forced-colors / high contrast
Turn on Windows High Contrast Mode (or emulate forced-colors in DevTools) and tab through again. The focus indicator must still be visible — outline-based rings survive, box-shadow-only rings do not.
Focus Visible is a manual check — automated tools cannot reliably judge whether a ring is "visible enough." Pair a keyboard walkthrough with the Keyboard Accessibility Guide and scan a live page with the URL Accessibility Auditor.
Frequently asked questions
What does WCAG 2.4.7 Focus Visible require?
WCAG 2.4.7 requires that any keyboard-operable interface has a mode where the keyboard focus indicator is visible. In plain terms: when someone moves through your page with the Tab key, they must always be able to see which element currently has focus. It is a Level AA success criterion, so it applies to the vast majority of legal and contractual accessibility requirements, including the ADA and Section 508.
Is it ever acceptable to use outline: none in CSS?
Only if you replace the outline with another clearly visible focus indicator. Writing outline: none (or outline: 0) on a focusable element with no replacement removes the one cue keyboard users rely on and fails 2.4.7. If you want a custom look, suppress the default ring and add your own — for example a box-shadow ring, a thicker border, or a background change — scoped to :focus-visible so it shows for keyboard users.
What is the difference between :focus and :focus-visible?
:focus matches any time an element is focused, including after a mouse click, which is why custom :focus styles sometimes leave a ring lingering after a click and tempt developers to remove it. :focus-visible matches only when the browser's heuristics say a visible indicator is appropriate — typically keyboard navigation — so you can show a strong ring for keyboard users without it appearing on every mouse click. Style :focus-visible for the keyboard indicator and you get the best of both.
How much contrast and thickness does the focus indicator need?
2.4.7 itself only requires that the indicator is visible; it does not set a numeric contrast or size threshold. The stronger guidance comes from WCAG 2.2: 2.4.11 Focus Not Obscured (AA) requires the focused element is not entirely hidden by other content, and 2.4.13 Focus Appearance (AAA) recommends an area at least as large as a 2px-thick perimeter of the component and a contrast ratio of at least 3:1 against adjacent colours. Aiming for a ring around 2px thick with 3:1 contrast is a good, future-proof default.
Does the default browser focus outline satisfy 2.4.7?
Yes. The default focus outline that browsers draw is a valid, conformant focus indicator, so the simplest way to pass 2.4.7 is to leave it alone. Problems start when a CSS reset or component library removes it without a replacement. If the default ring clashes with your design, restyle it rather than deleting it — keep an equally or more visible indicator.
How is 2.4.7 different from 2.4.3 Focus Order and 2.1.1 Keyboard?
They are the keyboard-access family. 2.1.1 Keyboard requires that everything is operable by keyboard at all. 2.4.3 Focus Order requires that focus moves through the page in a logical, meaningful sequence. 2.4.7 Focus Visible requires that, as focus moves, the user can always see where it is. You need all three: reachable by keyboard, in a sensible order, and visibly indicated at every step.