Tooltip

useTooltip is the open machine. Spread getTriggerProps on the trigger. Spread getTooltipProps on Tooltip.Root. Tooltip.Root is tip chrome only: children, className, style, and a dialog name when interactive. There is no Tooltip.Trigger or Tooltip.Content. Do not set interactive on Tooltip.Root.

Default is text-only role="tooltip". Hover waits 300ms. Focus opens at once. A coarse pointer uses focus only.

Pass interactive: true to useTooltip. The surface is a non-modal tip dialog. It uses popover="manual" and role="dialog". React Aria PreviewTrigger with Popover also forces role="dialog" on a hover tip that is not a modal. It never uses role="tooltip". Set exactly one of aria-label or aria-labelledby on Tooltip.Root. Links are allowed. Tab moves into those links. Hover can cross onto the panel. Escape returns focus to the trigger and does not reopen until that hold is released. There is no focus trap.

Placement is CSS anchors. The tip sits above the trigger and flips below when it cannot fit. There is no arrow and no placement prop. The tip is drawn in the top layer and placed against its trigger's untransformed box, so a trigger inside an element moved with a CSS transform gets its tip where the trigger would be without the transform.

Examples

Overflow chips and other non-button triggers use useTooltip, which has this demo's code. Mark a non-tabbable wrap with tabIndex={0}.

DesignTokens2 more

Interactive tip with a link. Set interactive: true on useTooltip. Set tooltip={false} on Button.Root so the hook owns the machine.

What goes where

ConcernAPI
Behavior

useTooltip — interactive, delays, open / onOpenChange, enabled, id

Chrome

Tooltip.Root — children, className, style, dialog name

Button sugar

Icon-only Button.Root tips its accessible name. Pass aria-label or aria-labelledby. A labeled button tips the full string only while the label overflows. tooltip={false} opts out. Fitting labeled buttons do not tip.

When to use

When: Short hint for a control (icon-only name, truncated label). A Button.Root tips its own icon-only or truncated label; any other trigger uses useTooltip + surface-only Tooltip.Root. Default tip is text-only (role="tooltip").

When not: Links inside the tip → useTooltip with interactive: true (non-modal tip dialog; links only). Action menus → Menu. Other actions → Popover. Long help → Description. Modal tasks → Dialog.

Props

The open machine's props are on useTooltip.

Tooltip.Root props
NameTypeRequiredDefaultDescription
childrenReact.ReactNodeno—Tooltip text, or short prose plus links when interactive.
classNamestringno—Class name for the tip surface.
styleReact.CSSPropertiesno—Style for the tip surface. Anchor position comes from getTooltipProps.
aria-labelstringno—Accessible name when no visible caption exists. Exactly one of aria-label or aria-labelledby when interactive.
aria-labelledbystringno—Id of the visible caption. Exactly one of aria-label or aria-labelledby when interactive.