Accessibility
How to make sure your tooltips are usable by everyone, including keyboard and screen reader users.
Tooltips are covered by several WCAG success criteria. The most relevant ones are:
- 1.4.13 Content on Hover or Focus — content shown on hover or focus must be dismissible (can be closed without moving the pointer or focus), hoverable (the pointer can move onto the content without it disappearing), and persistent (it stays visible until dismissed or no longer relevant).
- 2.1.1 Keyboard — the tooltip must be reachable and triggerable with a keyboard alone, not only with a pointer.
- 1.3.1 Info and Relationships — the relationship between the anchor and its tooltip must be conveyed programmatically, so assistive technologies can announce it.
The rest of this page shows how each of these maps to ReactTooltip props and markup. The full example at the end combines them.
ReactTooltip already opens the tooltip when the anchor receives keyboard focus (not just on hover), so most of the work is making sure your anchor is focusable and correctly associated with the tooltip.
Hoverable content (1.4.13)
By default the tooltip disappears when the pointer leaves the anchor element — which means the pointer can't be moved onto the tooltip, and any buttons or links inside it are unreachable.
Use the clickable prop so the pointer can move onto the tooltip content without it closing. See the Clickable tooltip example in the Getting Started section.
Dismissible with Esc (1.4.13)
Users must be able to close the tooltip without moving the pointer or focus. Enable the escape global close event so pressing the Esc key dismisses it.
<Tooltip
id="dismissible-tooltip"
globalCloseEvents={{ escape: true }}
/>
globalCloseEvents accepts other options too (scroll, resize, clickOutsideAnchor). See the options page for the full list.
Keyboard-accessible anchor (2.1.1)
ReactTooltip opens the tooltip when the anchor receives focus, but only focusable elements can receive keyboard focus. Interactive elements such as <a href="...">, <button>, and form controls are focusable by default.
If your anchor is a non-interactive element (like a <span> or <div>), make it focusable by adding tabIndex={0}.
// ✅ natively focusable
<button data-tooltip-id="my-tooltip">Help</button>
// ✅ made focusable
<span data-tooltip-id="my-tooltip" tabIndex={0}>Help</span>
Prefer a natively interactive element when the anchor is meant to be interacted with. Adding tabIndex={0} to a <span> makes it focusable but does not give it a button's role or behavior.
Associating the anchor and tooltip (1.3.1)
This one is handled for you. While the tooltip is open, ReactTooltip adds its id to the active anchor's aria-describedby attribute (merging with any values already there), and removes it again when the tooltip closes. This is what lets screen readers announce the tooltip content when the anchor is focused.
<button data-tooltip-id="my-tooltip">Help</button>
<Tooltip id="my-tooltip" content="Helpful description" />
Don't add the tooltip's id to the anchor's aria-describedby yourself. ReactTooltip manages it automatically, and a static attribute would point at the tooltip element even before it has been rendered (the tooltip is only added to the DOM once it opens).
ReactTooltip also renders the tooltip element with role="tooltip", so the automatic association gives assistive technologies the expected semantics.
Putting it all together
This example combines all of the above: a keyboard-focusable anchor whose content is reachable (clickable) and can be dismissed with Esc (globalCloseEvents). ReactTooltip adds the aria-describedby association automatically while the tooltip is open.
import { Tooltip } from 'react-tooltip'
<button data-tooltip-id="accessible-tooltip">◕‿‿◕</button>
<Tooltip
id="accessible-tooltip"
clickable
globalCloseEvents={{ escape: true }}
>
<a
href="https://react-tooltip.com"
target="_blank"
rel="noreferrer"
style={{ color: '#8ab4f8' }}
>
Read the docs
</a>
</Tooltip>
Try it with the keyboard: Tab to the anchor to open the tooltip, Tab again to move into the link, and Esc to dismiss it.
