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:

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 auto s and hint s |
Unrelated hint s |
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);
}

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:
- 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.
- 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.
- 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.