Tooltip
A <Tooltip> is a hover-revealed label. It exists so an icon-only or terse control still has a name. Anything longer than a sentence belongs in body copy, an Alert, or a Popover.
When to use
- Icon-only buttons (always — paired with an
aria-label). - Truncated labels (
<TooltipContent>shows the full string). - Power-user shortcuts (
Save · ⌘S).
Don’t use Tooltip for: error messages on form fields (FormError), persistent guidance (Alert), or restating a visible label.
Basic
<TooltipProvider> <Tooltip> <TooltipTrigger asChild> <Button variant="outline">Hover me</Button> </TooltipTrigger> <TooltipContent>This explains what the button does.</TooltipContent> </Tooltip></TooltipProvider>Icon-only button
For icon-only buttons, the Tooltip is the only visible label. Add aria-label on the button so screen readers announce it without hover.
<TooltipProvider> <Tooltip> <TooltipTrigger asChild> <Button variant="ghost" size="icon-sm" aria-label="Help"> <IconHelp /> </Button> </TooltipTrigger> <TooltipContent>What is this?</TooltipContent> </Tooltip></TooltipProvider>Sides
<TooltipContent side="top" /> {/* default */}<TooltipContent side="right" /><TooltipContent side="bottom" /><TooltipContent side="left" />API
TooltipProvider
| Prop | Type | Default | Description |
|---|---|---|---|
delayDuration | number | 0 | Milliseconds before the tooltip opens on hover. |
skipDelayDuration | number | 300 | After this long without a hover, the next hover re-applies delayDuration. |
TooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "top" | Preferred side. Radix flips automatically if there is no room. |
sideOffset | number | 0 | Distance in px between trigger and tooltip. |
align | "start" | "center" | "end" | "center" | Alignment along the chosen side. |
Design guidelines
✓ Do
- Pair every icon-only button with both a Tooltip and an aria-label so the action has a name in two channels.
- Keep content under one sentence. If you need two, use a Popover.
- Use the Button primitive's built-in tooltip prop when the trigger is a button — it composes Tooltip for you.
✗ Don't
- Restate the visible label in the tooltip ("Save" → tooltip "Save"). That is noise.
- Put interactive controls inside TooltipContent. Tooltips are not popovers.
- Open a tooltip on a disabled button without setting disabledReason — see Button.
Accessibility
- Provided by Radix: keyboard focus opens the tooltip; Esc closes it.
- Screen readers receive the
TooltipContenttext viaaria-describedbyon the trigger. - For icon-only buttons, set
aria-labelon the trigger — screen readers don’t wait for hover. - A disabled
<button>doesn’t fire hover events;<Button>handles this for you (wraps the disabled button so the wrapper picks up hover). For raw triggers, wrap manually.