Skip to content


It's recommended that tooltips are applied only to natively focusable elements like <button>. Most screenreader software will not announce the tooltip on an element like <div>.

Non-interactive tooltips are accessible by default. The default trigger for tooltips is "mouseenter focus". This means both a hover and focus via keyboard navigation will trigger a tooltip.

In addition, the reference element receives an aria-describedby attribute (configurable) once the tooltip is fully shown:

<button aria-describedby="tippy-1">Text</button>
<div id="tippy-1" role="tooltip" class="tippy-popper">
  <!-- inner elements -->

This allows screenreader software to announce the tooltip content describing the reference element. No work is required by you to achieve this functionality.


Although non-interactive tooltips are accessible by default, making interactive tooltips accessible requires a bit of work by you.

For UI elements like dropdowns, you should apply these attributes to the reference element:

  • aria-haspopup="true"
  • aria-expanded="false"
<!-- The element should have its own wrapper. -->
  <button aria-haspopup="true" aria-expanded="false">Text</button>

The following options are recommended:

tippy('button', {
  interactive: true,
  // `focus` is not suitable for buttons with dropdowns
  trigger: 'click',
  // Don't announce the tooltip's contents when expanded
  aria: null,
  // Important: the tooltip should be DIRECTLY after the reference element
  // in the DOM source order, which is why it has its own wrapper element
  appendTo: 'parent',
  // Let the user know the popup has been expanded
  onMount({ reference }) {
    reference.setAttribute('aria-expanded', 'true')
  onHide({ reference }) {
    reference.setAttribute('aria-expanded', 'false')

Using this technique, elements within the tippy can be tabbed to since they are directly after the reference element.

It's also possible to change the role of the tippy to something other than "tooltip":

tippy('button', {
  role: 'menu',