Accessible tooltips


TL;DR Make tooltips function like an accordion button: have the element trigger only when clicked (not hovered), then allow the user to close the tooltip with ESC or by hitting the tooltip button again.


A required email input field with in info icon next to it. A cursor is hovering over the icon and there is a speech bubble above it that says "We need your email address to help us find your account and send you a confirmation number."

A tooltip provides additional but not necessary information, most commonly found next to an input field.

Here’s how to design and mark up a tooltip in a way that is accessible and easy to use for all users.

Quick links:

What not to do

There are a few traditional patterns to tooltips that pose accessibility issues:

  • Trigger only on hover: tooltips that appear only when the user hovers are not keyboard accessible - how is the tooltip supposed to be triggered for someone who is not using a mouse?

  • Not persistent: many tooltips - usually the ones that appear on hover - disappear as soon as the user moves their mouse from the triggering element. This is a problem for users who need to move the mouse in order to read the content. Just as someone may use their finger to track the words they are reading on a page, users with reading disabilities or who are ESL may want/need to do the same with their mouse. It’s why WCAG 1.4.13 Content on Hover or Focus states that content that appears must be hoverable and persistent.

  • Only dismissable by movement: According to the same WCAG criterion, it’s a requirement that “a mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus”. Screen reader users rely on the location of their keyboard focus to understand where they are on a page. Forcing a user to move their keyboard focus can disrupt their orientation.

  • Title attribute not always recognized by assistive tech: The <title> attribute is often used to implement a tooltip. However, not all screen readers pick up a <title> attribute, especially if it’s competing with other labelling techniques - like a button with text and/or an aria-label.

What to do

Here are the principles that we want to accomplish when creating a tooltip:

  • Keyboard accessible: many users rely on keyboard only, either by choice or necessity, to navigate and interact with a page. Making the tooltip keyboard accessible is imperative. Otherwise, not all users will be able to access the helpful information it contains.

  • Intentionally triggered open by user: predictable page behaviour is a good thing for user experience. It allows users to understand what is happening on the page, and how to perform the actions they desire. Content appearing on hover or focus can surprise some users, causing confusion: “the user may not have intended to trigger the interaction; the user may not know new content has appeared; the new content may intefere with a user's ability to do a task”.By contrast, triggering content with a button hit is an intentional action performed by the user.

  • Hoverable: there are additional reasons to allow hovering over the tooltip, largely to do with zooming and screen magnification: “… magnified views may mean that the user needs to scroll or pan to completely view it, which is impossible unless the user is able to move their pointer off the trigger without the additional content disappearing. Another common situation is when large pointers have been selected via platform settings or assistive technology. Here, the pointer can obscure a significant area of the additional content.”

  • Persistent: Users need time to read a status message or tooltip. Allow the user to dismiss the tooltip on their own, rather than having it disappear automatically. (The only time it should disappear automatically is if it becomes invalid, like a “busy” status).

  • Dismissable: The user must be able to dismiss the tooltip without moving their cursor or the keyboard focus. This is often achieved by allowing ESC key to close the tooltip.

The solution

The easiest way to satisfy all the above requirements is to implement the tooltip as a button that triggers new content to appear, like an accordion.

Design solution

Often, developers will implement a tooltip using an attribute called <title>, which poses many of the aforementioned issues. This is why it’s important to explicitly indicate in your designs the expected functionality.

The same email input and tooltip as above, this time with "<button> Name: Information: Why are we asking for your email?" tagged next to the info icon and "tooltip closes on ESC" next to the tooltip bubble

Use Figma design annotations to indicate that the triggering element (usually the “i” or “?” icon) should be a button. Since this is an icon, we need to make sure the button’s function is communicated programmatically to assistive technology. We do this by including a name - in this case, “Information: Why are we asking for your email?” - which the developer can determine the best way to implement. Also state that the tooltip should close on ESC.

Two notes:

  1. Include the word “Information” so voice activation users can call on the button using a logical name (Thanks Kevin Bonett, Ian Lloyd and Grace Snow for the feedback on this one).

  2. You likely don’t need to indicate other keyboard behaviour, like button opens on SPACE and ENTER or that the keyboard focus should remain on the button when triggered. This is standard behaviour of the <button> element and will happen automatically when used. Like any interactive element though, you should indicate what the focus state looks like.

Make sure to keep open communication with your developers to explain why you’re recommending this implementation! Especially if they’re new to accessibility, they may not know these useful tips.

Code solution

Avoid using the <title> attribute for tooltips. It poses many accessibility issues and is meant for additional description, not informative content.

Instead, mark up a tooltip as a button, which opens an adjacent window when triggered.

We also need to indicate the button’s state: sighted users can see when the tooltip window opens, but how does a low vision or blind person know the button did something without audio feedback? That’s why we use <aria-expanded>, which assistive technologies announce for users. It gets toggled true/false using JavaScript depending on the state:

<button aria-expanded="true">
   Information: Why are we asking for your email?
</button>

If the button is meant to be an icon rather than text, use CSS to implement the visual styling but use HTML to ensure the button has an accessible, programmatic name. We can do that with classes or, in this case, a visually hidden image with an alt text:

<button aria-expanded="true">
   <img class="visually-hidden" alt="Information: Why are we asking for your email?" />
</button>

The tooltip content is an adjacent <div> that shows/hides using a class, which is toggled via JavaScript based on the button’s state. Indicate to assistive technologies the programmatic relationship between the tooltip trigger and content via <aria-controls> and ID:

<button aria-expanded="true" aria-controls="tooltip-window">
   Information: Why are we asking for your email?
</button>
<div class="expanded" id="tooltip-window">
   We need your email address to help us find your account and send you a confirmation number
</div>

Finally, having additional ways to close the tooltip is useful for users. Use JavaScript to allow users to close the tooltip with ESC. You can also include a “Close” button in the tooltip window. Just like our “i” icon, make sure if that close button is an X icon, it is marked up in a way that it still has an accessible name.

How to test

Use your keyboard to test the functionality of this element.

  • Tab to the triggering button. Make sure you can see where your keyboard focus is at all times.

  • If the tooltip shows when the triggering element receives focus, make sure you can tab into the tooltip window without it closing. If you can’t, then this fails WCAG 1.4.13 Content on Hover or Focus.

  • Ideally, the tooltip window only opens when the user actively triggers it open. This would be a mouse click or by hitting Enter.

  • After the tooltip window opens, tab away from the triggering button. Expected behaviour is that the tooltip window stays open, even when user tabs away.

  • Tab back to the triggering button. When hitting the button again, expected behaviour is that the tooltip window closes.

  • Can the tooltip window be closed by hitting ESC key? This isn’t mandatory behaviour but desirable.

  • Finally, check that the state is being announced to assistive technologies. Either inspect the code if you feel comfortable, or spin up a screen reader and make sure state is announced when the button is triggered.

Exceptions

Keyboard accessibility, predictability and time allowance are concepts to always include in any design or markup.

  • Web creators are not responsible for the styling or interactions of the tooltip that appears with <title>. That being said, it’s good to ask why that tooltip is being used; <title> tooltip should only be used to further describe the given element, not to provide new information. If it’s valuable information, include it in text or an accessible tooltip.

  • Error messages are not required to be dismissable, according to WCAG 1.4.13 Content on Hover or Focus. They must still be persistent and hoverable.


Find out more about Aleph Accessibility's auditing, training and consulting services. Or get in touch to start or accelerate your accessibility journey.

Next
Next

Can AI make the web more accessible?