Search topics
Tooltips that vanish on approach and can't be dismissed
The pop-up text shows only while the pointer is on its button, sits a gap away from it, covers the field below, and ignores Escape.
The problem
People who zoom, magnify or move the pointer slowly can't reach the pop-up text to read it, and can't hide it when it covers what they need.
A checkout summary lists the delivery fee with a small ? button beside it. Point at the button and a dark box of pop-up text appears a little below: "Free on orders over $50. Otherwise $6 to most addresses." Move the pointer down to read it, and it disappears the moment the pointer leaves the button. Tab to the button and the pop-up text appears again, this time on top of the coupon code field. Press Escape and nothing happens; the only way to uncover the field is to move focus away from the button.
The pop-up text is shown by a CSS rule on the button's own :hover and :focus, and it sits 8 pixels below the button. The pointer has to cross that gap to reach the pop-up text, and the button stops being hovered on the way, so the pop-up text closes: it is not hoverable. Nothing listens for Escape, so pop-up text that covers other content can't be dismissed without moving focus or the pointer. Success criterion 1.4.13 asks for both, and for the pop-up text to stay until the user dismisses it or moves away, which this one does.
The failure is worst at high zoom, where the pop-up text may open partly off screen and the only way to see the rest is to move toward it.
3 of 10 groups affected
- No vision (not affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited vision Magnifier and zoom users see only part of the screen, so they move the pointer to bring the pop-up text into view. It closes as soon as the pointer leaves the button, and the pop-up text is never read.
- Limited manipulation People with tremors drift off the small button and lose the pop-up text. Keyboard users who open it by focus can't hide it again without moving focus, so it keeps covering the field below.
- Limited language, cognitive and learning abilities People who read slowly lose the pop-up text when the pointer moves, and have to find the button and hover again to finish it.
The button has a name and the pop-up text is ordinary text, so a static scan finds nothing. The failure only shows when someone moves the pointer from the button toward the pop-up text, or presses Escape while it is open. Sibling selectors like .trigger:hover + .note are the usual answer to "show a tooltip on hover", and AI coding tools write them with a margin for breathing room, which is exactly the gap that closes the pop-up text.
Try it
Point at the ? beside Delivery fee, then move down onto the pop-up text.
Can you read all of the pop-up text? Press Tab to reach the button, then Escape: can you see the coupon field again?
Broken Can you fix this?
Delivery fee Free on orders over $50. Otherwise $6 to most addresses. $6
A recreated demo. The broken version is intentionally inaccessible.
The fix
Keep the pop-up text open while the pointer or focus is on the trigger or the pop-up text, and let Escape hide it.
- 1The pointer can move onto the pop-up text without it closing.
- 2Escape hides the pop-up text without moving focus or the pointer.
- 3The pop-up text stays until the user dismisses it or leaves, never on a timer.
<p class="fee"> Delivery fee <button type="button" class="tip-trigger" aria-describedby="fee-tip" aria-label="Delivery fee details">?</button> <span role="tooltip" id="fee-tip" class="tip-note">Free on orders over $50. Otherwise $6 to most addresses.</span></p><label for="coupon">Coupon code</label><input id="coupon">The pop-up text belongs to the button's hover alone, so crossing the 8-pixel gap closes it. Escape does nothing, and the pop-up text covers the coupon field until focus moves on. The markup is already a correct tooltip, with role="tooltip" and aria-describedby: the role tells a screen reader what the pop-up text is, but it adds no behaviour, so the failure stays.
The pop-up text is inside .tip, and its bridge covers the gap, so the pointer stays on the component all the way from the button to the pop-up text. It closes only when both hover and focus have left, with no timer. Escape hides it without moving anything, and it stays hidden until the user leaves and comes back. aria-describedby lets a screen reader read the pop-up text with the button even while it is hidden.
Both pass. The hover tooltip keeps the pop-up text one glance away for mouse users and works in every browser, but the script, the bridge and the Escape handling are yours to maintain, and on a touch screen the pop-up text still depends on focus. With the hover tooltip, a screen reader reads the pop-up text as soon as the button has focus, through aria-describedby. The toggletip leaves the browser to open, close and return focus, and needs only the short script that announces the text; it behaves the same for mouse, keyboard and touch, at the cost of a press before the pop-up text shows or is read. Choose the hover tooltip when the pop-up text is a short label people expect to see by pointing, as on icon-only toolbar buttons. Choose the toggletip when the pop-up text is information people need to read, such as fees, rules or password requirements.
CSS alone can make pop-up text hoverable: .tip:hover .tip-note, .tip:focus-within .tip-note keeps it open on the pop-up text as well as the button. It is not a fix on its own, because Escape still can't hide it; add the keydown handler. Escape is required only when the pop-up text covers or replaces other content. Pop-up text placed where it hides nothing may skip it, but layouts change at zoom, so it is safer to support Escape everywhere.
role="tooltip" belongs only on text that appears on hover or focus and describes its trigger, and the browser does nothing with it but announce it. It is the hover tooltip's role. The toggletip leaves it out, because its pop-up text opens on click and the button already says whether it is open.
Don't use the title attribute for anything people need. The browser draws that tooltip, so 1.4.13 doesn't apply to it, but it never appears on keyboard focus or touch, and it can't be styled or reached. Never hide pop-up text on a timer: a slow reader loses it, and the criterion asks for it to stay.
Keep the pop-up text short and free of links or buttons. Interactive content belongs in a non-modal dialog or a disclosure, as in panel-dismissal, not in a tooltip. If your component library supplies a tooltip, test the three checks below on it; many open on the trigger's hover alone and close on a short delay.
Verify the fix
5 checks.
Test with: Mouse, Keyboard, Zoom, Screen reader
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared tooltip component changes.
Limits
This covers a short piece of pop-up text tied to one button. It doesn't cover menus, dialogs or pop-ups with links inside them, or content that appears on scroll or after a delay. Test your real tooltips at the zoom levels and with the assistive technology your users have.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.