WCAG Success Criteria · Level AA
WCAG 2.4.7: Focus Visible
WCAG 2.4.7 requires that any keyboard-operable user interface has a visible focus indicator so users can always see which element currently has keyboard focus. This is essential for keyboard-only users, people with motor impairments, and anyone who cannot use a mouse.
- Level AA
- Wcag
- Wcag 2 2 aa
- Operable
- Accessibility
What This Rule Means
WCAG 2.4.7 Focus Visible requires that every interactive element on a web page â links, buttons, form inputs, custom widgets, and any other keyboard-operable component â displays a visible focus indicator when it receives keyboard focus. In plain terms, when a user presses the Tab key to move through a page, they must be able to see exactly which element is currently active.
The criterion does not mandate a specific visual style for the focus indicator. It only requires that some visible change occurs. That said, a barely perceptible indicator â for example, a one-pixel dotted outline that blends into the background â may technically pass 2.4.7 but still fail the more demanding WCAG 2.4.11 (Focus Appearance) introduced in WCAG 2.2. Under 2.4.7 alone, any discernible visual change is sufficient.
What counts as a pass: A focus indicator passes if a sighted user tabbing through the page can identify which element is focused without relying on screen-reader announcements or other non-visual cues. Common acceptable implementations include browser-default outlines, custom CSS outline or box-shadow rules, underline changes, or background-color shifts applied on :focus or :focus-visible.
What counts as a fail: A failure occurs when a developer removes the default browser focus ring â typically via outline: none or outline: 0 in CSS â and does not replace it with an equivalent custom indicator. Failures also occur when a custom component (built with <div> or <span> elements) is made keyboard-focusable via tabindex but receives no visible style change on focus.
Official exceptions: WCAG notes that the criterion applies only to keyboard-operable interfaces. Components that are purely decorative or explicitly excluded from the tab order (via tabindex='-1') are not required to show a focus indicator, because they cannot receive focus through normal keyboard navigation.
Why It Matters
Focus visibility is foundational to keyboard accessibility, and keyboard accessibility is the gateway to access for a wide range of disability groups. Approximately 26% of adults in the United States live with some form of disability according to the CDC, and many of these individuals rely on keyboards or keyboard-emulating assistive technologies rather than pointing devices.
Motor-impaired users â including people with conditions such as ALS, cerebral palsy, repetitive strain injury, or Parkinson's disease â frequently rely on keyboards, switch devices, sip-and-puff controllers, or eye-tracking software. All of these input methods depend on the browser's keyboard focus model. If the focus indicator is invisible, these users cannot determine where they are on the page, cannot activate the correct control, and may be entirely locked out of critical tasks such as submitting a form, completing a purchase, or navigating a menu.
Low-vision users who do not use a screen reader but may magnify the screen also depend on visible focus. When they zoom into a portion of the page, the visible focus ring tells them which element is active and guides their interaction.
Cognitive and attention-related disabilities also benefit from clear focus indicators. Users with ADHD or memory difficulties often lose track of their position on a complex page; a prominent focus indicator provides a reliable visual anchor.
A concrete real-world scenario: consider a user with multiple sclerosis who browses an e-commerce site using only a keyboard because mouse precision has become difficult. They tab through the product page to reach the "Add to Cart" button. If the developer has suppressed the focus ring, the user sees no indication of where focus is. They press Enter and either nothing happens (focus landed on a non-interactive element) or the wrong action is triggered. The result is frustration, task abandonment, and lost revenue for the business â all preventable with a single CSS rule.
Beyond disability, focus indicators benefit all users in situations where mouse use is inconvenient: power users navigating by keyboard shortcut, laptop users without an external mouse, and users filling out long forms. Visible focus also improves SEO indirectly by encouraging semantic HTML and proper tab order, both of which search engine crawlers reward.
Related Axe-core Rules
WCAG 2.4.7 requires manual testing because automated tools cannot reliably determine whether a focus indicator is visible. Axe-core and similar engines can detect that a CSS rule such as outline: none exists, but they cannot assess the rendered visual result across all themes, high-contrast modes, and browser rendering engines. The following explains the testing landscape:
- Manual testing required â focus-visible suppression: Axe-core does not ship a dedicated rule that definitively flags 2.4.7 failures, because doing so would require rendering the page, tabbing through every element, and performing pixel-level contrast analysis on the focus indicator â a task beyond static or DOM-level analysis. Instead, testers must manually tab through the page and visually confirm that each interactive element shows a focus change.
- Partial signal from
css-orientation-lockand style checks: Some axe-core configurations flag the presence ofoutline: 0oroutline: nonein stylesheets as a best-practice warning, but this is a heuristic, not a definitive violation check, because the rule may be overridden by a valid custom focus style elsewhere in the cascade. - Why automation falls short: A focus indicator may be hidden only in certain states (e.g., when a modal is open), only for certain element types, or only in certain color themes. These conditional failures require a human tester to navigate each interactive element in the actual rendered environment and confirm visibility. Tools like axe DevTools Pro can assist by highlighting elements that have
outline: noneapplied, but the final pass/fail determination must be human.
How to Test
- Automated pre-scan: Run axe DevTools (browser extension or CLI) or Google Lighthouse on the page. Look for any best-practice or experimental warnings related to focus styles. While these do not definitively confirm a 2.4.7 failure, they surface elements worth inspecting. In Lighthouse, check the "Accessibility" category for focus-related findings. Export the report and note all flagged interactive elements.
- Manual keyboard tab test: Disconnect or move your mouse away. Press Tab repeatedly from the top of the page and navigate through every interactive element â links, buttons, inputs, dropdowns, modals, tabs, accordions, and date pickers. At each stop, confirm that the focused element is visually distinguishable from its unfocused neighbors. Record any element where focus arrival produces no visible change.
- Reverse tab test: Use Shift+Tab to navigate backward through the page and repeat the visual check. Some implementations only break focus visibility in one direction due to CSS specificity issues.
- NVDA + Firefox test: Open Firefox with NVDA running. Use Browse Mode (arrow keys) and then switch to Forms Mode (Enter) to interact with form controls. Confirm that every element NVDA announces as focused also shows a visible indicator on screen â useful for catching discrepancies between AT focus and browser focus.
- VoiceOver + Safari test (macOS/iOS): Enable VoiceOver and use Tab or VO+Right Arrow to move through interactive elements. Visually verify the focus ring on screen matches what VoiceOver announces.
- JAWS + Chrome test: Use JAWS in virtual cursor mode and then application mode. Tab through interactive controls and confirm the visible focus indicator appears on every focused element.
- High-contrast mode test: Enable Windows High Contrast Mode (or macOS Increase Contrast) and repeat the Tab test. Some focus indicators rely on colors that disappear in high-contrast themes; the indicator must remain visible in these modes.
- CSS inspection: Open browser DevTools, select an interactive element, focus it by pressing Tab until it is active, and inspect the computed styles. Verify that no rule sets
outline: noneoroutline: 0without a compensating focus style. Also check for:focus-visiblevs:focusto ensure keyboard-triggered focus is covered.
How to Fix
Global outline suppression without replacement â Incorrect
<!-- CSS resets that remove all focus indicators globally -->
<style>
* {
outline: none; /* Removes focus ring from every element */
}
</style>
<a href='/products'>View Products</a>
<button type='submit'>Buy Now</button>
Global outline suppression without replacement â Correct
<!-- Remove the global outline: none reset.
Provide a custom focus style that is visually clear. -->
<style>
/* Respect users who prefer reduced motion */
:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
</style>
<a href='/products'>View Products</a>
<button type='submit'>Buy Now</button>
<!-- Now both elements show a high-contrast blue outline when focused via keyboard -->
Custom div-based button with no focus style â Incorrect
<!-- A div styled as a button, made focusable, but missing :focus CSS -->
<style>
.fake-btn {
display: inline-block;
padding: 10px 20px;
background: #e00;
color: #fff;
cursor: pointer;
}
/* No :focus or :focus-visible rule defined */
</style>
<div class='fake-btn' tabindex='0' role='button'
onclick='addToCart()' onkeydown='handleKey(event)'>
Add to Cart
</div>
Custom div-based button with no focus style â Correct
<!-- Add :focus-visible to the custom component so keyboard
users see a clear indicator when this element is focused -->
<style>
.fake-btn {
display: inline-block;
padding: 10px 20px;
background: #e00;
color: #fff;
cursor: pointer;
}
.fake-btn:focus-visible {
outline: 3px solid #ffcc00;
outline-offset: 3px;
}
</style>
<div class='fake-btn' tabindex='0' role='button'
onclick='addToCart()' onkeydown='handleKey(event)'>
Add to Cart
</div>
<!-- The yellow outline appears only on keyboard focus, not on mouse click -->
Focus ring hidden inside a modal overlay â Incorrect
<!-- Modal applies overflow:hidden and a stacking context that clips
the default outline, making it invisible -->
<style>
.modal-body {
overflow: hidden; /* Clips outlines that extend beyond the element */
border-radius: 8px;
}
</style>
<div class='modal-body'>
<button>Confirm Order</button>
<button>Cancel</button>
</div>
Focus ring hidden inside a modal overlay â Correct
<!-- Use box-shadow instead of outline so it renders
inside the stacking context and is never clipped -->
<style>
.modal-body {
overflow: hidden;
border-radius: 8px;
}
.modal-body button:focus-visible {
/* box-shadow is not clipped by overflow:hidden --
it stays within the element's own box -->
box-shadow: 0 0 0 3px #005fcc;
outline: none; /* Remove default to avoid double ring */
}
</style>
<div class='modal-body'>
<button>Confirm Order</button>
<button>Cancel</button>
</div>
Common Mistakes
- Adding
outline: noneto a base CSS reset without auditing which elements it affects. Many popular resets (e.g., older versions of normalize.css or Bootstrap utilities) suppress focus rings globally. Always follow up with an explicit:focus-visiblerule that restores visibility for keyboard users. - Relying solely on
:focuswhen:focus-visibleis more appropriate â or vice versa. Using only:focusapplies the indicator on mouse clicks too, which can look odd. Using only:focus-visiblewithout a:focusfallback may leave older browsers without any indicator. Test in all target browsers. - Applying
outline: noneinside a component library theme override without understanding the cascade. A single override in a theme file can silently erase focus indicators for every component that inherits from it, including third-party widgets. - Using a focus color that has insufficient contrast against the element or page background. A light-gray outline on a white background technically adds an outline but may be imperceptible. While 2.4.7 does not mandate a specific contrast ratio, 2.4.11 does â and low-contrast focus indicators are a common source of audit failures even when developers believe they have complied.
- Setting
overflow: hiddenorclip-pathon a container, which clips the browser's default outline. The fix is to switch tobox-shadow-based focus indicators, which render within the element's own box and are not clipped by parent overflow rules. - Forgetting focus indicators on interactive elements inside SVG or Canvas components. Custom chart tooltips, SVG-based icon buttons, and canvas-based drawing tools often have no native focus styling. These require explicit ARIA roles,
tabindex, and:focus-visibleCSS or JavaScript-driven visual feedback. - Removing focus visibility only in production CSS (e.g., via a post-processor or build step) while leaving it visible in the development environment. This causes the development team to pass their local QA while shipping broken accessibility to end users.
- Applying a focus indicator only to the
<a>element but not torole='link'span elements used for SPA navigation links. Every keyboard-focusable element â regardless of its native tag â needs a visible focus state. - Hiding focus rings only in certain viewport widths via media queries, assuming mobile users always touch the screen. Tablet users with Bluetooth keyboards and users in landscape orientation who rely on keyboard input are left without any focus indicator.
- Using JavaScript to call
.blur()immediately after programmatic focus to prevent the focus ring from appearing. This is a critical error that completely removes focus visibility and must never be used as a design shortcut.
Relation to Turkey's Accessibility Regulations
Turkey's Presidential Circular 2025/10, published in the Official Gazette No. 32933 on June 21, 2025, establishes binding web and mobile accessibility requirements for a broad range of entities operating in Turkey. The circular mandates conformance with WCAG 2.2 at Level AA for covered organizations, making WCAG 2.4.7 Focus Visible a directly enforceable requirement rather than merely a best-practice recommendation.
The entities covered by the circular include public institutions and agencies, e-commerce platforms, banks and financial service providers, hospitals and healthcare organizations, telecommunications companies with 200,000 or more subscribers, travel agencies, private transport companies, and private schools authorized by the Ministry of National Education (MoNE). For all of these organizations, failing to provide visible focus indicators on their digital interfaces is a regulatory non-compliance issue, not merely a usability shortfall.
The EriĆilebilirlik Logosu (Accessibility Logo), issued by the Ministry of Family and Social Services, serves as the official certification mark that covered entities can display to demonstrate conformance. Achieving the Accessibility Logo requires passing a formal audit at WCAG 2.2 Level AA. WCAG 2.4.7 is one of the AA criteria auditors will evaluate, typically through manual keyboard testing as described in the testing section above. An organization whose site suppresses focus rings or fails to implement visible focus on custom components will not pass the audit required for the logo.
For Turkish e-commerce platforms in particular, focus visibility has direct commercial implications: accessible sites reach a wider user base, including customers with motor impairments who shop exclusively via keyboard or switch access, and compliance with Presidential Circular 2025/10 protects organizations from administrative action. Building focus-visible patterns into the component library from the outset â rather than retrofitting after an audit â is the most cost-effective path to maintaining the EriĆilebilirlik Logosu and meeting Turkey's accessibility obligations.
KĂ€llor och referenser
- W3C Understanding 2.4.7 Focus Visible
- W3C Techniques for 2.4.7
- WebAIM: Keyboard Accessibility
- MDN: :focus-visible pseudo-class
- MDN: :focus pseudo-class
- W3C Technique C15: Using CSS to change the presentation of a user interface component when it receives focus
- W3C Technique G149: Using user interface components that are highlighted by the user agent when they receive focus
