Tooltip
A small label that appears on hover or keyboard focus to explain an element. Use for icon-only buttons, truncated text, and keyboard shortcuts. Requires <TooltipProvider> as an ancestor. Built on @base-ui/react/tooltip.
Anatomy
TooltipProvider sets the shared delay for all descendant tooltips. Each Tooltip wraps a TooltipTrigger and a TooltipContent. The content includes a built-in positional arrow.
Positioning
The side prop controls which side the tooltip appears on (default: "top"). Auto-flips when space is insufficient.
side="top"side="right"side="bottom"side="left"Delay
TooltipProvider accepts a delay prop (ms) applied to all descendant tooltips. Override per-tooltip by wrapping in a separate provider.
delay={0} — instantBest for persistent toolbars.
delay={500} — delayedReduces noise on hover-heavy UIs.
Examples
Icon toolbar
With keyboard shortcut
Truncated text
This is a very long filename that gets truncated.txt
Design Guidelines
Do
- Use for icon-only buttons. Every icon button without a visible label needs a tooltip to communicate its action.
- Include keyboard shortcuts in content. Showing
⌘KorCtrl+Sbeside the label teaches users the shortcut naturally. - Keep content to one short phrase. Tooltips are supplemental — one line max.
Don't
- Don't put interactive content inside. Links and buttons inside a tooltip are unreachable on touch devices — use Popover instead.
- Don't use for required instructions. Tooltip content is only visible on hover/focus — never put information users must act on.
- Don't wrap elements that are already labelled. If the button has visible text, a tooltip is redundant noise.
Developer Reference
Accessibility
role="tooltip"on the content — linked to the trigger viaaria-describedby.- Tooltip is shown on keyboard focus (
:focus-visible) in addition to hover — keyboard users see it. TooltipProvidermust wrap all tooltip usage — it controls the shared delay and manages group hover behaviour.- Arrow element is automatically positioned by the Base UI popup engine.
Usage
import {
TooltipProvider,
Tooltip,
TooltipTrigger,
TooltipContent,
} from "@/components/ui/tooltip"
// Wrap your app (or section) with TooltipProvider
<TooltipProvider>
{/* Basic tooltip */}
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" size="sm" aria-label="Bold">
<Bold className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Bold</p>
</TooltipContent>
</Tooltip>
{/* With keyboard shortcut */}
<Tooltip>
<TooltipTrigger asChild>
<Button aria-label="Copy">
<Copy className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p className="flex items-center gap-2">
Copy <kbd className="rounded bg-muted px-1 text-xs">⌘C</kbd>
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
// Custom delay
<TooltipProvider delay={500}>...</TooltipProvider>
// Positioning
<TooltipContent side="right" align="start">...</TooltipContent>