Search for a command to run...
A small floating label that clarifies icon-only triggers. Glass-pill chrome, scales in from the trigger, dismisses on blur. Never use to hide critical info — content must remain understandable without ever hovering.
Mount TooltipProvider once near the root of the tree (e.g. in your app layout). It coordinates the open delay across every tooltip so the first hover waits, but subsequent rapid hovers fire instantly.
TooltipProviderWraps a subtree so its tooltips share open/close timing. Forwards every Radix Tooltip.Provider prop.
| Prop | Type | Default | Description |
|---|---|---|---|
delayDuration | number | 300 | Delay (ms) before a tooltip opens after pointer enter. Lower = more responsive, higher = avoids accidental fires. |
skipDelayDuration | number | 300 | Window (ms) after a tooltip closes during which the next tooltip opens with no delay. Makes toolbar scanning feel fast. |
disableHoverableContent | boolean | false | When true, content closes the moment the trigger un-hovers (it isn't itself hoverable). Use for purely informational tooltips. |
TooltipThe state container. Forwards every Radix Tooltip.Root prop.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Uncontrolled initial state. |
onOpenChange | (open: boolean) => void | — | Fires when the open state changes. |
delayDuration | number | — | Per-tooltip override of the provider's delayDuration. |
TooltipTriggerThe element that opens the tooltip on hover / focus. Use asChild to project the behavior onto your own component (Button, Link, IconButton) — the trigger is not a styled wrapper.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render the child element directly. Almost always what you want. |
TooltipContentThe floating glass pill. Portaled to the document root. Forwards every Radix Tooltip.Content prop.
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "top" | Preferred side. Floating-UI flips automatically when the preferred side would clip outside the viewport. |
sideOffset | number | 6 | Gap (px) between trigger and tooltip. Pairs with the side-aware slide-in-from-* entrance. |
align | "start" | "center" | "end" | "center" | Alignment along the opposite axis. |
collisionPadding | number | Padding | 0 | Viewport padding the tooltip stays inside when colliding with the edge. |
avoidCollisions | boolean | true | Disable to lock the tooltip to its preferred side even when clipped. |
className | string | — | Extra classes — content is a glass pill with text-fg-high; usually you want the defaults. |
The content sets origin-(--radix-tooltip-content-transform-origin) so it scales in from the trigger, not from its own center. Subsequent rapid hovers within skipDelayDuration get data-state="instant-open" and use the same animation (without the wait) for a snappy toolbar feel.
Use tooltips to label icon-only triggers (settings cog, copy button) where the visual alone
is ambiguous. The icon's aria-label carries the same text for screen readers.
Mount one TooltipProvider near your app root. The shared skipDelayDuration is what makes
scanning a toolbar feel instant — separate providers per tooltip break that.
Pass asChild on TooltipTrigger and let your own Button / Link / IconButton be the
trigger. The trigger should look like a normal control, not a tooltip wrapper.
Hide critical information behind a tooltip. Hover is unreliable on touch devices and impossible for some assistive tech — anything the user must know belongs in the visible UI.
Use tooltips for long descriptions or interactive content (links, buttons inside). Reach for
HoverCard (rich, hoverable) or Popover (click-anchored, focus-trapped) instead.
Re-label a control that already has visible text ("Save" button with a "Save" tooltip). The duplicate noise trains users to ignore tooltips that do matter.