Tooltips and popovers
Add automatically positioned supplemental labels and click-triggered contextual content with accessible state.
Floating feedback
Both controllers position against their trigger and keep the panel inside the viewport. Tooltips supplement an existing accessible name; popovers disclose richer contextual content.
Tooltip
<button class="bs-btn bs-btn-outline" type="button" data-bs-tooltip="Copies a shareable link" data-bs-placement="top">
Copy link
</button>Popover
<button class="bs-btn bs-btn-primary" type="button" data-bs-popover="Changes are saved for 30 days." data-bs-title="Draft retention" data-bs-placement="bottom">
Retention details
</button>import { initTooltips } from "@boobstrap/boobstrap/js/tooltip";
import { initPopovers } from "@boobstrap/boobstrap/js/popover";
const tooltips = initTooltips(document);
const popovers = initPopovers(document);React
React hooks keep the floating panel in your JSX. Prop getters connect IDs, visibility, placement, hover/focus or click behavior, Escape dismissal, outside-pointer dismissal, scroll dismissal, refs, and repositioning.
import { usePopover, useTooltip } from "@boobstrap/react";
export function ContextHelp() {
const tooltip = useTooltip({ id: "copy-tip", placement: "top" });
const popover = usePopover({ id: "retention-popover", placement: "bottom" });
return (
<>
<button className="bs-btn" {...tooltip.getTriggerProps()}>Copy link</button>
<div className="bs-tooltip" {...tooltip.getTooltipProps()}>Copies a shareable URL</div>
<button className="bs-btn" {...popover.getTriggerProps()}>Retention details</button>
<div className="bs-popover" aria-labelledby="retention-title"
{...popover.getPopoverProps()}>
<strong className="bs-popover-header" id="retention-title">Retention</strong>
<div className="bs-popover-body">Logs are retained for 30 days.</div>
</div>
</>
);
}Vue
Vue composables expose the same consumer-owned panels as reactive prop objects. Bind each getter to the exact trigger or panel it describes.
<script setup>
import { usePopover, useTooltip } from "@boobstrap/vue";
const tooltip = useTooltip({ id: "copy-tip", placement: "top" });
const popover = usePopover({ id: "retention-popover", placement: "bottom" });
</script>
<template>
<button class="bs-btn" v-bind="tooltip.getTriggerProps()">Copy link</button>
<div class="bs-tooltip" v-bind="tooltip.getTooltipProps()">
Copies a shareable URL
</div>
<button class="bs-btn" v-bind="popover.getTriggerProps()">Retention details</button>
<div class="bs-popover" aria-labelledby="retention-title"
v-bind="popover.getPopoverProps()">
<strong class="bs-popover-header" id="retention-title">Retention</strong>
<div class="bs-popover-body">Logs are retained for 30 days.</div>
</div>
</template>See the React adapter guide and Vue adapter guide for controlled state, lifecycle events, SSR, and cleanup behavior.
Accessible names
A tooltip is supplementary. Keep visible button text or another accessible name on the trigger.
Interaction
Tooltips open on hover and focus. Popovers open on activation and dismiss with Escape, an outside pointer action, or page scrolling.
Content
Controller content is plain text by design. Use a dialog for interactive controls, structured content, or a workflow.
Floating API
| Class or hook | Purpose |
|---|---|
.bs-tooltip | Generated supplemental label with role="tooltip". |
.bs-popover, .bs-popover-header, .bs-popover-body | Generated contextual panel and its structured regions. |
.bs-floating-arrow | Placement-aware generated arrow. |
data-bs-placement | Prefers top, bottom, start, or end. |
bs:tooltip:*, bs:popover:* | Cancelable before-events and completion events. |