WCAG Success Criteria · Level AA

WCAG 1.4.13: Content on Hover or Focus

WCAG 1.4.13 requires that additional content appearing on pointer hover or keyboard focus is dismissible, hoverable, and persistent — ensuring users with low vision, motor impairments, and cognitive disabilities can access and interact with tooltip-style content without losing it unexpectedly.

  • Level AA
  • Wcag
  • Wcag 2 2 aa
  • Perceivable
  • Accessibility

What This Rule Means

WCAG 1.4.13 addresses a common interaction pattern on the web: content that becomes visible when a user hovers a pointer over an element or moves keyboard focus to it. This includes tooltips, sub-menus, custom dropdown hints, date-picker popovers, and any other overlay that appears in response to hover or focus events. The criterion applies whenever such content is not controlled natively by the browser (for example, the native title attribute tooltip is exempt), and it establishes three core requirements that must all be met simultaneously.

Dismissible: The user must be able to dismiss the additional content without moving pointer focus or keyboard focus. The standard mechanism for this is pressing the Escape key. This prevents the overlay from obscuring other page content in a way the user cannot resolve — particularly critical for users who have magnified the screen and cannot simply glance elsewhere.

Hoverable: If the additional content appeared because the user hovered over a trigger element, the user must be able to move their pointer over the newly appeared content without it disappearing. If a tooltip vanishes the moment the cursor leaves the trigger element, users cannot read lengthy content, copy text from it, or activate links or controls within it.

Persistent: The additional content must remain visible until the hover or focus trigger is removed, the user dismisses it (for example via Escape), or the information is no longer valid. Content must not disappear on a timer or after an arbitrary delay while the user's pointer or focus is still on the trigger or the overlay itself.

A pass requires all three conditions to be satisfied. A fail occurs if any single condition is missing — for example, a tooltip that disappears when the pointer moves from the trigger toward the tooltip (not hoverable), or one that auto-closes after three seconds (not persistent), or one that cannot be closed without moving focus away (not dismissible). The one official exception carved out by WCAG is when the visual presentation of the additional content is entirely controlled by the user agent — browser-native tooltips produced solely by the title attribute fall into this category and are exempt, though they carry their own accessibility limitations.

Why It Matters

This criterion primarily benefits users who experience difficulty controlling standard mouse or keyboard interactions, users who rely on screen magnification, and users who process information more slowly. Understanding who is affected helps teams prioritize the fix correctly.

Users with low vision often use screen magnification software such as ZoomText or the built-in OS magnifier, which means they see only a small portion of the screen at high zoom levels. When a tooltip appears, it may be partially off-screen, and the user must pan toward it. If the tooltip disappears the moment the pointer leaves the trigger, the user cannot pan to read it. According to the World Health Organization, approximately 2.2 billion people globally live with some form of vision impairment, and a significant portion of those who use computers rely on magnification rather than a screen reader.

Users with motor impairments — including people with Parkinson's disease, tremors, or limited fine motor control — may use alternative pointing devices, head pointers, or eye-tracking systems. Precise pointer control is difficult for these users, meaning moving from a small trigger element to a small tooltip without accidentally leaving both can be nearly impossible if the hover area is not forgiving. The hoverable requirement directly addresses this.

Users with cognitive disabilities may read slowly or need to re-read content. A tooltip that auto-dismisses after a few seconds does not give these users enough time to absorb the information, and a tooltip that cannot be dismissed without moving focus may trap their attention in a confusing interaction state.

Consider a concrete scenario: a banking website displays account interest rate details inside a tooltip that appears when the user hovers over a small information icon. A low-vision user zoomed to 400% sees only part of the page at once. They hover over the icon, the tooltip appears, and they begin to move their pointer toward the tooltip to read the fine print — but the tooltip vanishes immediately because it is only tied to the parent element's hover state. The user cannot access the required disclosure information. This is not merely a usability inconvenience; in regulated industries it may constitute a legal accessibility barrier.

Beyond disability-specific impact, correct implementation of this criterion also improves general usability for all users on touch-and-keyboard hybrid devices, reduces support requests caused by "disappearing" UI elements, and signals interface quality to users and auditors alike.

WCAG 1.4.13 requires manual testing. Automated tools cannot reliably detect violations because the criterion involves time-based and pointer-movement behaviors that static DOM analysis cannot evaluate. No single axe-core rule maps directly to this criterion, but the following considerations explain why automation falls short and what to look for during manual review.

  • Manual testing required — hover behavior: Automated scanners inspect the DOM and CSSOM at a point in time; they cannot simulate moving a pointer from a trigger element toward a newly rendered tooltip and observe whether the tooltip persists. A tool could theoretically detect that a CSS :hover pseudo-class hides a child element when the parent loses hover, but it cannot distinguish between intentional dismissal and a failure of the hoverable requirement without simulating pointer paths.
  • Manual testing required — Escape dismissal: Detecting whether pressing Escape closes an overlay requires JavaScript event simulation that goes beyond axe-core's current rule set. Axe can flag missing ARIA roles on popups or missing aria-expanded attributes, but it cannot verify that a keydown listener for Escape is wired to a close function and actually hides the element.
  • Manual testing required — persistence / auto-dismiss: A tooltip that hides itself via a setTimeout call after three seconds will appear fully valid in a static scan taken within that window. Only a tester who watches the overlay over time — or reviews the JavaScript source — can identify an auto-dismiss timer as a violation.
  • Complementary axe rules to run alongside manual checks: While not directly testing 1.4.13, running rules such as aria-tooltip-name (ensuring tooltips have accessible names), color-contrast (ensuring tooltip text is legible), and focus-visible (ensuring focused triggers are visually identifiable) can surface related issues that compound the impact of 1.4.13 failures.

How to Test

  1. Automated baseline scan: Run axe DevTools or Lighthouse on the page containing hover/focus-triggered content. Note any flagged issues with tooltip roles, contrast, or focus visibility — these do not confirm 1.4.13 compliance but establish a baseline. Record which elements trigger overlay content so you can target them in manual steps.
  2. Identify all hover/focus-triggered content: Scroll through the page and systematically hover over every interactive element — icon buttons, links with extra descriptions, form field hints, navigation items, data table headers, and chart data points. List each element that causes additional content to appear.
  3. Test the hoverable requirement: For each identified trigger, hover over it to reveal the overlay, then slowly move the pointer from the trigger element onto the overlay content itself. The overlay must remain visible throughout this movement. If it disappears before the pointer reaches it, the criterion fails.
  4. Test the dismissible requirement: While an overlay is visible (triggered by either hover or keyboard focus), press the Escape key. The overlay must close. If it does not close, the criterion fails. Do this test with the pointer still on the trigger and also with the pointer over the overlay.
  5. Test the persistent requirement: Trigger an overlay and then leave your pointer stationary on the trigger or the overlay for at least 10–15 seconds. The overlay must remain visible throughout. If it fades, times out, or disappears without user action, the criterion fails.
  6. Keyboard-only test: Tab through the page using only the keyboard. When focus lands on a trigger that reveals additional content, verify: (a) the content appears, (b) pressing Escape closes it, and (c) the content does not disappear on its own while focus remains on the trigger. Use NVDA with Firefox, JAWS with Chrome, and VoiceOver with Safari to confirm screen readers also expose the content correctly.
  7. Screen magnification test: Set browser zoom to 400% or activate OS-level magnification. Repeat the hover tests. Confirm that a user who must pan the viewport to reach the tooltip can do so without the tooltip vanishing.
  8. Review JavaScript source: Search the codebase for setTimeout, mouseleave, mouseout, and blur event handlers associated with overlay hide logic. Confirm that hide logic is not triggered while the pointer is over the overlay or while the trigger retains focus, and that no auto-dismiss timer is set.

How to Fix

CSS-only tooltip that disappears on mouseleave — Incorrect

<!-- Tooltip only shown via CSS :hover on parent; disappears as soon as
     the pointer moves off the trigger toward the tooltip text -->
<span class='tip-wrapper'>
  Info
  <span class='tooltip'>This is the tooltip content.</span>
</span>

<!-- CSS (illustrative) -->
<!--
.tooltip { display: none; }
.tip-wrapper:hover .tooltip { display: block; }
-->

CSS-only tooltip that disappears on mouseleave — Correct

<!-- Correct: tooltip is also shown when the pointer is over the tooltip itself,
     and the gap between trigger and tooltip is covered so pointer movement
     does not accidentally dismiss the overlay. -->
<span class='tip-wrapper'>
  Info
  <span class='tooltip' role='tooltip' id='tip1'>This is the tooltip content.</span>
</span>

<!-- CSS (illustrative) -->
<!--
.tooltip { display: none; position: absolute; }
.tip-wrapper:hover .tooltip,
.tooltip:hover { display: block; }
/* Use padding or a transparent pseudo-element bridge between trigger and tooltip */
-->

JavaScript tooltip with no Escape key dismissal — Incorrect

<button aria-describedby='tip2' data-tooltip='Account balance details'>
  Balance
</button>
<div id='tip2' role='tooltip' hidden>Account balance details</div>

<script>
// Only mouseenter/mouseleave — no keyboard or Escape handling
document.querySelector('button').addEventListener('mouseenter', () => {
  document.getElementById('tip2').removeAttribute('hidden');
});
document.querySelector('button').addEventListener('mouseleave', () => {
  document.getElementById('tip2').setAttribute('hidden', '');
});
</script>

JavaScript tooltip with no Escape key dismissal — Correct

<button aria-describedby='tip2' data-tooltip='Account balance details'>
  Balance
</button>
<div id='tip2' role='tooltip' hidden>Account balance details</div>

<script>
const btn = document.querySelector('button');
const tip = document.getElementById('tip2');

function showTip() { tip.removeAttribute('hidden'); }
function hideTip() { tip.setAttribute('hidden', ''); }

// Show on hover and focus
btn.addEventListener('mouseenter', showTip);
btn.addEventListener('focus', showTip);

// Hide only when pointer leaves BOTH trigger AND tooltip
btn.addEventListener('mouseleave', (e) => {
  // Short delay allows pointer to reach the tooltip
  setTimeout(() => {
    if (!tip.matches(':hover') && !btn.matches(':hover')) hideTip();
  }, 100);
});
tip.addEventListener('mouseleave', () => {
  if (!btn.matches(':hover')) hideTip();
});

// Hide on blur (keyboard)
btn.addEventListener('blur', hideTip);

// Dismissible via Escape key — required by 1.4.13
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape' && !tip.hidden) hideTip();
});
</script>

Auto-dismissing tooltip with setTimeout — Incorrect

<button id='info-btn'>More info</button>
<div id='tip3' role='tooltip' hidden>Here is the additional information for this field.</div>

<script>
document.getElementById('info-btn').addEventListener('mouseenter', () => {
  const t = document.getElementById('tip3');
  t.removeAttribute('hidden');
  // Violation: auto-dismisses after 3 seconds regardless of user state
  setTimeout(() => t.setAttribute('hidden', ''), 3000);
});
</script>

Auto-dismissing tooltip with setTimeout — Correct

<button id='info-btn' aria-describedby='tip3'>More info</button>
<div id='tip3' role='tooltip' hidden>Here is the additional information for this field.</div>

<script>
const btn2 = document.getElementById('info-btn');
const tip3 = document.getElementById('tip3');

// No setTimeout — tooltip persists until user removes hover/focus or presses Escape
function show() { tip3.removeAttribute('hidden'); }
function hide() {
  setTimeout(() => {
    if (!tip3.matches(':hover') && !btn2.matches(':hover') && document.activeElement !== btn2) {
      tip3.setAttribute('hidden', '');
    }
  }, 100);
}

btn2.addEventListener('mouseenter', show);
btn2.addEventListener('focus', show);
btn2.addEventListener('mouseleave', hide);
btn2.addEventListener('blur', hide);
tip3.addEventListener('mouseleave', hide);
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') tip3.setAttribute('hidden', '');
});
</script>

Common Mistakes

  • Using only CSS :hover without covering the gap between the trigger and the tooltip: When there is even a 1–2 px gap between the trigger element and the tooltip container, moving the pointer between them causes the hover state to drop, hiding the tooltip before the user reaches it. Use a transparent pseudo-element or overlapping padding to bridge this gap.
  • Binding hide logic to mouseleave on the trigger without checking whether the pointer has moved onto the tooltip: The tooltip disappears the instant the cursor moves off the trigger, even if the destination is the tooltip itself. Always check tip.matches(':hover') before hiding, or use a short debounce delay.
  • Forgetting to wire focus and blur events alongside mouseenter and mouseleave: Keyboard-only users who tab to the trigger will never see the tooltip if only mouse events are handled, making the associated information completely inaccessible without a mouse.
  • Not adding an Escape key listener, assuming clicking away is sufficient: Keyboard users and screen magnification users cannot easily "click away" from an overlay. Escape is the expected and required dismissal mechanism for this criterion.
  • Placing the Escape listener only on the trigger element instead of the document: If the user moves focus to the tooltip or to another element, a listener scoped to the trigger will not fire. The Escape handler must be on the document or a shared ancestor that always receives key events when the overlay is open.
  • Using setTimeout to auto-close tooltips after a fixed duration: Any timer-based dismissal that fires while the pointer is still on the trigger or tooltip, or while the trigger still has keyboard focus, is a direct violation of the persistent requirement. Remove all auto-dismiss timers from hover/focus-triggered overlays.
  • Triggering tooltip visibility exclusively through title attribute replacement with custom styling: Developers who remove the native title tooltip and replace it with a custom version must implement all three 1.4.13 requirements themselves. The exemption for browser-native tooltips does not extend to custom JavaScript reproductions of the same pattern.
  • Not testing with screen magnification at 400% zoom: A tooltip that appears accessible at normal zoom may be partially off-screen at high zoom levels, requiring the user to pan — and if it dismisses before they can pan to it, the test that passed at 100% zoom fails in real use conditions.
  • Applying pointer-events: none to the tooltip container: This CSS property prevents the pointer from ever being considered "over" the tooltip, making it impossible to satisfy the hoverable requirement regardless of other logic. Tooltips that users might need to interact with or simply hover over to keep visible must never have pointer-events: none.
  • Treating ARIA role='tooltip' alone as sufficient for compliance: Adding role='tooltip' and aria-describedby is important for screen reader accessibility but addresses a different layer of the problem. These ARIA attributes do not automatically make content dismissible, hoverable, or persistent — the interaction behavior must still be implemented explicitly.

Relation to Turkey's Accessibility Regulations

Turkey's Presidential Circular 2025/10, published in the Official Gazette numbered 32933 on June 21, 2025, establishes a formal accessibility mandate that incorporates WCAG standards by reference. The circular requires covered entities to implement web accessibility measures aligned with internationally recognized guidelines, and Level AA conformance — which includes WCAG 1.4.13 — is both strongly encouraged and required for entities seeking the Accessibility Logo (Erişilebilirlik Logosu) issued by the Ministry of Family and Social Services (Aile ve Sosyal Hizmetler Bakanlığı).

The circular covers a broad range of entity types operating in Turkey. Public institutions and government bodies at all administrative levels are required to make their digital services accessible. In the private sector, the obligation extends to e-commerce platforms, banks and financial service providers, hospitals and private healthcare institutions, telecommunications operators with 200,000 or more subscribers, travel agencies, private transport companies, and private schools operating under authorization from the Ministry of National Education (Millî Eğitim Bakanlığı).

WCAG 1.4.13 is particularly relevant in Turkish digital contexts where tooltip and popover patterns are widely used in e-government portals (such as e-Devlet integrations), banking and fintech interfaces that display fee or rate information in tooltips, and healthcare appointment systems that surface additional instructions via hover-triggered overlays. A banking platform failing 1.4.13 could prevent low-vision customers from reading interest disclosures delivered via tooltip — a scenario that carries both accessibility and financial consumer protection implications.

For entities pursuing the Erişilebilirlik Logosu, an accessibility audit will include manual testing of hover and focus behaviors precisely because automated tools cannot catch these violations. Organizations using an accessibility overlay SDK such as Accsible should ensure that any widget-injected tooltips, guided tour popovers, or contextual help panels introduced by the SDK itself fully comply with all three 1.4.13 requirements — dismissible via Escape, hoverable without dismissal, and persistent until user action. Failing to do so would introduce new barriers through the very tool intended to improve accessibility, undermining both regulatory compliance and user trust.