Overlays
Tooltip
A short label on hover and on focus.
When to reach for it
Examples
default
Notes
A short label on hover and on focus.
asChild on the trigger by design: the tooltip must not add a wrapper that swallows the trigger's own focus ring or breaks a flex row. It also means the child has to be focusable — a <div> trigger gets no keyboard tooltip, which is the failure this API shape makes obvious rather than silent.
Not a replacement for an accessible name. An icon-only button still needs its own aria-label; the tooltip repeats that name for sighted pointer users.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| childrenrequired | ReactNode | The element the tooltip describes. Must be focusable. | |
| contentrequired | ReactNode | The tip. Keep it to a phrase — a tooltip is unreachable on touch and invisible to a reader who is scanning, so anything a user NEEDS belongs on the page instead. | |
| side | ComponentProps<typeof TooltipPrimitive.Content>['side'] | 'top' | — |
| sideOffset | number | 6 | — |
Also accepts everything in Pick<ComponentProps<typeof TooltipPrimitive.Root>, 'open' | 'defaultOpen' | 'onOpenChange' | 'delayDuration'>. Those are forwarded to the underlying element and are not listed row by row.
Re-exports
TooltipProvider = TooltipPrimitive.ProviderWrap the app — or the smallest subtree that has tooltips — once. Radix needs it to share the open/close timing between neighbouring triggers, which is what stops a row of icon buttons flashing a tooltip per hover.
Accessibility
- The trigger is asChild, so the child must be focusable — a div trigger simply has no keyboard tooltip, which this API shape makes obvious rather than silent.
- Not an accessible name. An icon-only button still needs its own aria-label.