1.4.13 Content on Hover or Focus
Level: AA | Principle: Perceivable | Since: WCAG 2.1 | Automation: Manual
What This Means
When hovering or focusing on an element triggers additional content to appear (tooltips, dropdowns, popovers), that content must meet three requirements:
- Dismissible — the user can close it without moving hover or focus (typically via Escape)
- Hoverable — the user can move the pointer over the new content without it disappearing
- Persistent — the content remains visible until the user dismisses it, moves hover/focus away, or the information is no longer valid
This prevents tooltips that vanish before they can be read or that obscure other content with no way to dismiss them.
Who This Affects
- Screen magnifier users — tooltips may appear outside the magnified viewport; they need to move the pointer to read the content without it disappearing
- Users with cognitive disabilities — need time to read and process popup content
- Keyboard users — focus-triggered content must remain until focus moves away
Common Pitfalls
1. Tooltip that disappears when you try to hover over it
<!-- Bad: tooltip vanishes when pointer leaves the trigger -->
<span class="trigger" title="Helpful information">
Hover me
</span>
The native title attribute tooltip cannot be hovered over and disappears when the pointer moves away from the trigger.
2. Popover with no dismiss mechanism
<!-- Bad: no way to close without moving focus -->
<div class="popover" role="tooltip">
This popover blocks content underneath and has no close button.
</div>
3. Content that disappears on a timer
// Bad: tooltip auto-hides after 2 seconds
setTimeout(() => tooltip.hide(), 2000);
How to Fix
Build a hoverable, dismissible tooltip
<!-- Good: custom tooltip that meets all three requirements -->
<div class="tooltip-wrapper">
<button aria-describedby="tip1">More info</button>
<div id="tip1" role="tooltip" class="tooltip">
This tooltip stays visible when hovered and can be dismissed with Escape.
</div>
</div>
.tooltip {
display: none;
position: absolute;
z-index: 10;
padding: 0.5rem;
background: #333;
color: #fff;
border-radius: 4px;
}
.tooltip-wrapper:hover .tooltip,
.tooltip-wrapper:focus-within .tooltip {
display: block;
}
/* Hoverable: tooltip stays when pointer moves to it */
.tooltip:hover {
display: block;
}
// Dismissible: Escape key closes the tooltip
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
document.querySelectorAll('.tooltip').forEach(t => t.style.display = 'none');
}
});
How to Test
- Hover over every element that triggers additional content (tooltips, popovers, dropdown previews) and move the pointer onto the popup content. It must stay visible.
- Press Escape while the popup is visible. It must close without moving hover or focus elsewhere.
- Tab to elements that trigger focus-based popups (e.g., tooltip on focus). Verify the content appears and remains until focus moves away.
- Check that no popup disappears on a timer before the user can read it.
- Pass: All hover/focus-triggered content is dismissible with Escape, hoverable without disappearing, and persistent until the user dismisses it.
- Fail: Any tooltip vanishes when the pointer moves to it, cannot be dismissed with Escape, or disappears on a timer.
axe-core Rules
No automated axe-core rules. This criterion requires manual testing.