Popover = hint

Published: February 26, 2025

Chrome 133 builds upon the existing popover feature by introducing a new mode: popover="hint". This browser-managed mode enables a new stacking context that simplifies creating tooltips and similar ephemeral floating elements. It reduces developer effort while maintaining design flexibility.

Introduction and history

The Popover API, introduced in Chrome 114, lets you create accessible floating UI such as menus and tooltips. By default, popover="auto" handles light-dismiss functionality and focus management for you, without the need for additional scripting, as covered in Introducing the Popover API. When opening a popover="auto" popover, all other non-ancestor popovers with popover="auto" will be closed, which makes for an ergonomic API that does the most sensible thing.

Popovers closing other popovers

<div id="p1" popover>First Popover</div>
<button popovertarget="p1">Open popover 1</button>
<div id="p2" popover>Second Popover</div>
<button popovertarget="p2">Open popover 2</button>

In this example, opening popover 2 will close popover 1, since popover="auto" only allows one such popover to be open at a time.

While this behaviour works nicely for menus and dialogs, it may create issues when multiple types of floating UI need to co-exist. For example a menu and a tooltip both using popover="auto" may clash, where opening the tooltip closes the menu. This might seem an uncommon situation, but it comes up a lot in a modern application-style UI. For example, the menus on github.com's header use popovers for both the menus and the tooltips, allowing both to be visible at the same time under certain conditions:

An open menu.
The GitHub menu.

One way to solve this is to use popover="manual" for the tooltip elements, which allows for full control of the popover with scripting. However, this requires reimplementing stacking behavior, light-dismissal, and focus management—precisely the tasks the Popover API was designed to handle. This prompted us to explore ways to extend the API to provide this missing functionality.

Through developer research, we identified two common stacking contexts:

  • Persistent UI: For example, menus and dialogs.
  • Ephemeral UI: For example, hovercards and tooltips.

To accommodate both, popover="hint" introduces a second stack, distinct from popover="auto", ensuring that menus remain open even when tooltips appear. Rather than introducing multiple stacking contexts for different UI types—which would essentially re-invent z-index—this approach keeps things simpler by defining just two broad categories: persistent UI (auto) and ephemeral UI (hint). This strikes a balance between flexibility and avoiding resurfacing the same issues you faced prior to using popover.

Behavior of the new value

Both popover="auto" and popover="hint" support light dismiss, meaning they automatically close when the user clicks outside them, or hits Esc on the keyboard. In this regard both styles are identical.

When it comes to the force-hiding of other popovers, popover="auto" closes all other auto and hint popovers when opened, ensuring that only one such popover is active at a time (the one exception here is nested popovers, explained below). popover="hint", on the other hand, only force-hides other hint popovers, allowing menus and tooltips to remain open and coexist.

Where they differ most is in their nesting behavior. popover="auto" supports nesting, allowing a child popover to remain open within another parent popover. popover="hint" has a special nesting behavior, which is where the separate "stacks" come in. When a hint popover is inside an auto popover, it joins the auto stack to maintain contextual grouping, meaning that it will stay open until other auto or hint popovers cause it to force-hide. This provides intuitive behaviour, where tooltips don't interrupt other menus or popovers.

Finally, for very different use cases, there is always popover="manual", which does not come with any of these behaviors baked in, allowing you to define the precise functionality and behavior you need.

popover="auto" popover="hint" popover="manual"
Light dismiss Yes Yes No
Force-hides: Unrelated autos and hints Unrelated hints Nothing
Nesting: Yes Special (described previously) N/A—no light dismiss

Hover triggering

A common UX pattern is for tooltips and hovercards to be hover triggered. Hovering the mouse over an element of interest, for a period of time, causes the hovercard to be shown. Currently, that behavior needs to be implemented via JavaScript, for example by adding listeners for the mouseenter and mouseleave events. However, another API is under development that should make hover triggering declarative: the Interest Invokers API.

This API is still a work in progress, but the general idea is to add an attribute called interesttarget to many element types, which confers hover-triggering behavior on them:

<a interesttarget="my-hovercard" href="...">
  Hover to show the hovercard
</a>
<span popover="hint" id="my-hovercard">
  This is the hovercard
</span> 

With the preceding HTML, hovering the <a> link will automatically show the my-hovercard popover. Moving the pointer off that element will hide the popover. All without JavaScript!

Examples

<button>An interesting button</button>
<div popover="hint">More info about the button</div>
[popover] {
  margin: 0;
  inset: auto;
  position-area: bottom right;
}
const button = document.querySelector('button');
const popover = document.querySelector('[popover]');

button.onmouseenter = () => {
  setTimeout(() => {
    popover.showPopover({source: button});
  }, 500);
}

button.onmouseleave = () => {
  setTimeout(() => {
    popover.hidePopover();
  }, 500);
}
Button with tooltip.
Try this out live.

This example uses popover="hint" to build a basic tooltip, which provides more information about the button when the button is hovered with the mouse. The hover activation is provided by event handlers for mouseenter and mouseleave with simple 0.5 second delays. Note that there are a few details that aren't handled by this example:

  1. Hovering the popover itself does not prevent the hovering away from a triggering element from closing the popover. So it's not possible to copy or paste text from the popover, for example.
  2. There is no "debouncing": hovering the button for a small fraction of a second is enough to trigger the popover, even if the button is quickly hovered off of before the delay time elapses. In this case, the tooltip "flickers" open and closed quickly.
  3. The example is not accessible at all: any user not using a mouse cannot access the tooltip content.

These shortcomings can be fixed with additional JavaScript. For example, focus (or perhaps keydown and keyup) event handlers would need to be added in order to support keyboard-based activation of the popover. For an explanation of the things that need to be correctly handled to make sure the tooltip is accessible see this great blog post from Sarah Higley. All of these issues (and more) will be automatically handled declaratively by the Interest Invokers API.

Find out more

See the feature explainer or the HTML specification for more detail.