Tooltips & Popovers
|
This section documents Bootstrap 5.x as implemented by the official Bootstrap project. No specific patch version is pinned. Unlike the other reference sections on this site, no single reference book underpins it: the content was generated with the assistance of AI from general knowledge of Bootstrap, and should be verified against the current official documentation at getbootstrap.com/docs before relying on it in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
Tooltips and popovers both attach a small floating overlay to a trigger element — a short label for a
tooltip, a richer title-plus-body panel for a popover. They are covered together because they share the same
underlying mechanics: both are positioned by Popper.js, and, unlike the components on
Interactive Components, neither one activates from data-bs-*
attributes alone — both require an explicit JavaScript call to opt each element in.
Why explicit initialization is required
Bootstrap enables tooltips and popovers "opt-in" rather than automatically, for performance: computing a
Popper.js position for every element that merely carries a title attribute on every page would be wasteful,
so only elements the page explicitly initializes get the behavior. The standard pattern selects every element
carrying the relevant data-bs-toggle value and constructs an instance for each:
const tooltipTriggers = document.querySelectorAll('[data-bs-toggle="tooltip"]');
tooltipTriggers.forEach((el) => new bootstrap.Tooltip(el));
const popoverTriggers = document.querySelectorAll('[data-bs-toggle="popover"]');
popoverTriggers.forEach((el) => new bootstrap.Popover(el));
This script must run after the DOM elements it queries exist — placed just before </body>, or inside a
DOMContentLoaded listener — otherwise querySelectorAll finds nothing and no tooltip or popover on the page
will ever show.
Tooltips
The markup itself only needs data-bs-toggle="tooltip" and a title attribute holding the tooltip’s text — the title is what Bootstrap’s JavaScript reads to build the tooltip’s content, and it is removed from the DOM
(so the browser’s own native title tooltip never doubles up with Bootstrap’s):
<button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top"
title="Saves the current document">
Save
</button>
<a href="#" data-bs-toggle="tooltip" data-bs-placement="right" title="Opens in a new tab">
External link
</a>
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach((el) => new bootstrap.Tooltip(el));
data-bs-placement accepts top, right, bottom, or left, and is only a preference — Popper.js still
flips it automatically if the tooltip would otherwise render outside the viewport (for example, a top
tooltip near the top edge of the page flips to bottom).
HTML content in a tooltip
By default the title text is inserted as plain text, escaping any markup it contains. Setting
data-bs-html="true" allows real HTML inside the tooltip — only worth doing for trusted, static content, since
it is otherwise an XSS vector if the title text ever comes from user input:
<button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-html="true"
title="<em>Emphasized</em> tooltip text">
Hover me
</button>
Popovers
A popover is structurally similar to a tooltip but supports both a title (the popover’s header) and a
separate data-bs-content (its body), and stays open until dismissed rather than only while hovering, when
combined with the focus/dismiss options below:
<button type="button" class="btn btn-primary" data-bs-toggle="popover" data-bs-placement="bottom"
title="Dismissible popover" data-bs-content="And here's some amplifying body content.">
Click to toggle popover
</button>
document.querySelectorAll('[data-bs-toggle="popover"]').forEach((el) => new bootstrap.Popover(el));
Popovers default to triggering on click rather than hover, which is why data-bs-toggle="popover" alone is
enough to make the example above open on click without any extra configuration.
Dismiss on next click
data-bs-trigger="focus" closes the popover as soon as the user clicks anywhere else on the page (moving focus
away from the trigger), which is the recommended pattern for a "dismissible on next click" popover — the
trigger element must be focusable for this to work, so a plain <a> needs tabindex="0" if it lacks an
href:
<button type="button" class="btn btn-secondary" data-bs-toggle="popover" data-bs-trigger="focus"
title="Dismissible" data-bs-content="Clicking anywhere else closes this popover.">
Dismissible popover
</button>
The JavaScript component API
Both components support the same instance-based API shape used across Bootstrap’s other stateful components
(see JavaScript Behavior for the general pattern): show(),
hide(), toggle(), and dispose(), retrieved either from the constructor’s return value or, for an instance
created elsewhere, via bootstrap.Tooltip.getInstance(el):
const el = document.getElementById("save-button");
const tooltip = new bootstrap.Tooltip(el, {
placement: "top",
title: "Saves the current document",
});
tooltip.show();
tooltip.hide();
tooltip.dispose(); // removes the tooltip and its event listeners entirely
// elsewhere, without a reference to the original instance:
bootstrap.Tooltip.getInstance(el)?.hide();
dispose() matters specifically for content that is removed from the DOM dynamically (a row deleted from a
table, a card removed from a list) — without disposing the tooltip/popover instance first, Popper.js keeps a
reference to the now-detached element and its positioning listeners are never cleaned up, a small but real
memory leak in a page that creates and destroys many such elements over its lifetime.
Custom triggers and events
The trigger option (or data-bs-trigger) accepts a space-separated combination of click, hover, focus,
and manual — manual disables all automatic triggering, leaving show()/hide()/toggle() as the only way
to control visibility, useful when a tooltip’s visibility should be driven by application logic rather than
direct user interaction with the trigger element itself.
Choosing between them
Use a tooltip for a short, supplementary label — what an icon-only button does, an abbreviation’s expansion — content the user does not strictly need to operate the page. Use a popover when there is more to say than fits in a one-line label, or when the content should stay visible while the user reads or interacts with it, rather than disappearing the instant the pointer moves away.
See the official Tooltips docs and the official Popovers docs for the complete option and event reference.