WCAG 2.4.7 Focus Visible: Why Visible Keyboard Focus Matters
WCAG 2.4.7 Focus Visible requires a clear keyboard focus indicator for every keyboard-operable element. This article explains why focus visibility matters, shows practical CSS patterns, lists common mistakes, and gives a step-by-step testing checklist for developers and testers.
WCAG 2.4.7 Focus Visible requires that keyboard focus is clearly visible when users navigate with the keyboard. Visible focus lets people who use Tab, arrow keys or assistive tech know which element will receive input next.
What WCAG 2.4.7 means for your site
The success criterion covers any keyboard-operable interface. If a user can reach an element by keyboard, its focus state must be visible. This applies to links, buttons, form controls, custom widgets and any interactive element that can receive focus.
Why visible keyboard focus matters
- Orientation. A visible indicator shows where the user is on the page.
- Control. It makes it possible to interact predictably with controls.
- Safety. Users avoid unintended actions because they can see what will respond to the next key press.
How browsers handle focus by default
Most browsers provide a built-in focus ring for native elements. That ring is sufficient for many cases. Problems arise when CSS removes or hides that ring without replacing it with an accessible alternative.
Implementation patterns that meet WCAG 2.4.7
Use the browser default focus when you can. When you need a custom look, replace the default with a clear, persistent indicator. Keep the visual change for keyboard users only where appropriate.
Simple replacement using outline
Common approach: remove the default outline only for mouse clicks and add a visible outline for keyboard focus. Use the :focus-visible pseudo-class to target keyboard focus without affecting mouse interactions. Example style text you can copy into your CSS:
/* show custom focus only for keyboard users */
.component:focus-visible { outline: 3px solid #2b7bd3; outline-offset: 2px; }
When you must style :focus (older browsers)
Some environments do not support :focus-visible. Then ensure your focus style is not removed globally. If you set outline: none, add a replacement rule for :focus:
.component:focus { box-shadow: 0 0 0 3px rgba(43,123,211,0.25); }
Custom widgets and ARIA
Custom controls built with role and ARIA must expose a keyboard focusable element. Use tabindex=“0” or a native control as the interaction target. Ensure the visible focus applies to the element that receives keyboard events.
Focus for links, buttons and form controls
Keep focus visible on anchors, buttons and input fields. Do not rely on hover effects. Make sure the visible indicator is large enough to see on small screens and on high-density displays.
Common mistakes and how to fix them
- Removing the outline without replacement. Fix: add an equally visible replacement using outline or box-shadow.
- Relying on color alone. Fix: combine color with thickness or offset so contrast and shape are clear.
- Hiding focus for mouse users only incorrectly. Fix: use :focus-visible to avoid showing focus on mouse click while still showing it for keyboard users.
- Applying focus styles to the wrong element. Fix: attach focus styles to the interactive element that receives keyboard events, not a parent wrapper unless the wrapper has tabindex.
Testing checklist for WCAG 2.4.7
- Navigate your site using Tab and Shift+Tab only. Confirm every interactive element shows focus.
- Activate controls with Enter or Space. Ensure focus state persists and moves predictably.
- Test custom widgets: verify element with tabindex receives focus and displays the indicator.
- Use keyboard navigation with and without a pointing device attached to catch focus-on-click issues.
- Try high-contrast mode and zoom. Ensure the focus indicator scales and remains visible.
- Run automated checks from tools such as Axe, WAVE or Accessibility Insights, then follow up with manual keyboard tests.
Practical example: making a custom button accessible
Scenario: you styled a div to look like a button and handled clicks with JavaScript. Step by step:
- Replace the div with a native button if possible. Native controls are focusable and provide keyboard behaviour by default.
- If you must use a non-native element, add tabindex=“0” so it receives focus and add keydown handlers for Enter and Space.
- Add a focus rule. Use :focus-visible for modern browsers and :focus as a fallback. Make the ring thick enough and offset so it does not clip.
- Verify with Tab navigation, then test with a screen reader to confirm interaction works.
Edge cases and mobile considerations
Touch-only devices do not show keyboard focus. However, some mobile users attach external keyboards. Keep focus styles responsive and test with keyboard-connected mobile devices if your audience might use them.
QA checklist for developers and testers
- Add focus styles for all interactive elements, including links, form controls and ARIA widgets.
- Prefer :focus-visible for better mouse/keyboard distinction.
- Do not remove outline globally. If you remove it, always replace it with an accessible alternative.
- Test at different zoom levels and in high-contrast modes.
- Include keyboard testing in your CI acceptance tests and manual test plans.
Where to read the official guidance
Consult the WCAG documentation for the exact language and examples of the Focus Visible success criterion. Also check the WCAG techniques pages for testable techniques and common failures.
Quick summary. Make focus visible and predictable. Use native controls where possible. When you override browser defaults, provide a clear, persistent focus indicator and test with keyboard navigation and assistive tools.