Popover and tooltip
Small, contextual overlays for displaying information or custom content.
The Idea React OverlayBox wrapper composes Bootstrap 6 tooltip or popover markup with
React-triggered behavior. It supports hover, focus, and click triggers with top, right, bottom, and
left placement. The popover sections adapt the Bootstrap Popover documentation; the tooltip
sections adapt the Bootstrap Tooltip documentation.
Popover
Overview
Click the button below to show and close a popover.
Things to know when using popovers:
- Bootstrap relies on Floating UI for dynamic positioning. The React wrapper instead positions the panel with Bootstrap's placement utilities inside the trigger's relative wrapper, so there is no positioning library or plugin to initialize.
- Popovers are rendered wherever
<OverlayBox>is mounted, next to the trigger. This keeps the content inside dialogs and other focus-managed containers without acontaineroption. - Set
titlefor the popover header anddetailfor the body. Withoutdetail, the wrapper renders a tooltip instead. - Triggering popovers on hidden elements will not work.
- Popovers for
.disabledordisabledelements must be triggered on a wrapper element. - When triggered from anchors that wrap across multiple lines, add
.text-nowrapto keep the panel centered on a single line. - The wrapper removes the panel and its
aria-describedbyreference when it closes or unmounts. - Popovers can be triggered from an element inside a shadow DOM.
- React escapes text by default. Pass JSX to
titleordetailwhen you intentionally need HTML; there is no separate sanitizer option.
The fade animation honors prefers-reduced-motion.
Examples
Live demo
Titles are set via the title prop and body content is set via detail.
Use title for the popover header, not the native HTML title attribute. The wrapper handles the
accessible association with aria-describedby.
Image content
Pass JSX to detail to place rich content, such as an image, inside the popover.
<OverlayBox
detail={<Image alt="idea2app" src="https://github.com/idea2app.png"/>}
title="view info"
trigger="click"
>
<Button
theme="primary"
variant="solid"
>
View
</Button>
</OverlayBox>Placement
Set placement to change the direction. Four options are available: top, right, bottom, and left.
Directions are mirrored when using Bootstrap in RTL.
Responsive placement
The Bootstrap plugin accepts breakpoint-prefixed placements such as top md:right lg:bottom. The
React wrapper takes a single placement value; choose it per viewport in your component or model
instead of passing a responsive string.
<OverlayBox placement={isWide ? 'right' : 'top'} title="Responsive popover" detail="…">
<Button>Open</Button>
</OverlayBox>Custom container
Bootstrap's container option moves the generated markup into another element when parent styles
interfere with positioning. The React wrapper always renders the panel inside its trigger wrapper,
so the content stays in the flow of the component—including inside a dialog, where focus is trapped
and the panel must remain a child of the dialog. If an ancestor clips the panel, adjust that
ancestor's overflow or move the trigger, rather than reparenting the overlay.
Custom popovers
Customize the appearance with the CSS variables on the panel. Set overlayClassName to scope the
overrides, then define the variables on that class:
.custom-popover {
--bs-popover-header-bg: var(--bs-primary-bg);
--bs-popover-header-color: var(--bs-primary-contrast);
--bs-popover-body-color: var(--bs-primary-contrast);
--bs-popover-border-color: var(--bs-primary-bg);
--bs-popover-arrow-border: var(--bs-primary-bg);
}
Dismiss on next click
Use the focus trigger to dismiss popovers on the user's next click of an element other than the
toggle element. Clicks and focus inside the popover itself do not dismiss it, so users can select
text or use controls in the content.
Use an <a> element with tabindex="0" and role="button" rather than a <button> for proper
cross-browser and cross-platform behavior.
A shown popover can also be dismissed by pressing Escape. A popover shown inside a dialog is dismissed on its own: the first Escape closes the popover and a subsequent one closes the dialog.
Disabled elements
Elements with the disabled attribute aren't interactive, meaning users cannot hover or click them
to trigger a popover or tooltip. Trigger the popover from a wrapper <div> or <span>, ideally made
keyboard-focusable with tabindex="0".
For disabled popover triggers, you may also prefer a ['hover', 'focus'] trigger so the popover
appears as immediate visual feedback; users may not expect to click a disabled element.
Tooltip
Overview
Hover the button below to see a tooltip. By default, the tooltip appears above its trigger element.
Things to know when using tooltips:
- Bootstrap relies on Floating UI for positioning; the React wrapper uses Bootstrap placement utilities and does not need the plugin.
- Tooltips are rendered next to the trigger and removed when closed.
- Provide a title; an empty overlay conveys nothing to users.
- Triggering tooltips on hidden elements will not work.
- Tooltips for
.disabledordisabledelements must be triggered on a wrapper element. - When triggered from hyperlinks that span multiple lines, add
.text-nowrapto keep the tip centered. - Tooltips can be triggered from an element inside a shadow DOM.
- The default trigger is both hover and focus, so keyboard users can reach the tooltip.
The fade animation honors prefers-reduced-motion.
Examples
Tooltips on links
Hover over the links below to see tooltips:
Custom tooltips
Customize the appearance with the CSS variables on the tip. Set overlayClassName to scope the
overrides, then define the variables on that class:
.custom-tooltip {
--bs-tooltip-bg: var(--bs-primary-bg);
--bs-tooltip-color: var(--bs-primary-contrast);
}
Placement
Set placement to change the direction. Hover over the buttons below to see the four tooltip
directions: top, right, bottom, and left. Directions are mirrored when using Bootstrap in RTL.
Responsive placement
As with popovers, the Bootstrap plugin accepts breakpoint-prefixed placements, while the React
wrapper takes one placement per mounted overlay. Select the value that matches the current layout.
Custom HTML
Pass JSX to the title prop to control the tooltip markup. React handles escaping and rendering, so
there is no html option.
With an icon:
Interactive tooltips
Move the pointer onto the tip to reach interactive content inside it, such as a link. The tooltip stays open while the pointer is over the trigger or the tip. It hides when the pointer leaves both, or when you press Escape. This helps satisfy the WCAG 1.4.13 "Content on Hover or Focus" success criterion.
Disabled elements
Elements with the disabled attribute aren't interactive, meaning users cannot focus, hover, or
click them to trigger a tooltip. Trigger the tooltip from a wrapper <div> or <span>, ideally made
keyboard-focusable with tabindex="0".
Accessibility
Keep popovers and tooltips accessible to keyboard and assistive technology users by only adding
them to HTML elements that are traditionally keyboard-focusable and interactive, such as links or
form controls. While other HTML elements can be made focusable with tabindex="0", this can create
annoying and confusing tab stops for keyboard users. Do not rely solely on hover as the trigger,
because it makes the overlay impossible to reach with a keyboard.
Avoid large amounts of content in a tooltip or popover that uses the same aria-describedby
association: assistive technologies announce the entire content as one continuous stream. Popovers
do not manage keyboard focus order; if you need interactive content, consider using a
Dialog instead.
CSS
Variables
Tooltips and popovers use local CSS variables for real-time customization. Override them through
overlayClassName or by targeting .tooltip and .popover in a scoped style. See the upstream
popover CSS and tooltip CSS for the complete variable and Sass map reference.
Usage
Bootstrap enables popovers and tooltips through a JavaScript plugin. Mount the React component instead—there is no instance to initialize, retrieve, or dispose:
<OverlayBox title="Popover title" detail="Popover content">
<Button>Toggle popover</Button>
</OverlayBox>The wrapper renders the panel, keeps aria-describedby in sync, and closes it on outside pointer
interaction or Escape.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Tooltip text or popover header. Required. |
detail | ReactNode | — | Popover body. When omitted, the overlay is a tooltip. |
placement | 'top' | 'right' | 'bottom' | 'left' | 'top' | Side of the trigger where the panel appears. |
trigger | 'click' | 'focus' | 'hover' or an array of them | ['hover', 'focus'] | Interactions that open the panel. |
delay | number | { show: number; hide: number } | 0 | Delay in milliseconds before showing or hiding. |
overlayClassName | string | — | Extra classes for the tooltip or popover panel, useful for scoped theming. |
Data attributes
The plugin's data attributes map directly to props:
| Bootstrap attribute | React prop |
|---|---|
data-bs-title | title |
data-bs-content | detail |
data-bs-placement | placement (one value; no responsive prefixes) |
data-bs-trigger | trigger (no manual; render the overlay conditionally instead) |
data-bs-custom-class | overlayClassName |
data-bs-html | Pass JSX to title or detail |
Methods and events
The plugin's show, hide, toggle, setContent, and instance methods do not exist in the React
wrapper. Render <Popover> or <Tooltip> directly when you need to control visibility or content:
<Popover title="Popover title" placement="top">
Popover content
</Popover>Likewise, use React state and lifecycle instead of show.bs.popover, shown.bs.tooltip, and the
other plugin events.