Tooltip
A tooltip names an icon-only control when you hover it or reach it with the keyboard.
<Tooltip>
<TooltipTrigger asChild>
<Button>…</Button>
</TooltipTrigger>
<TooltipContent>Copy address</TooltipContent>
</Tooltip>When to use
Section titled “When to use”- To show the name of an icon-only control, like copy, close or more. Icon button does this for you.
- To show a keyboard shortcut next to that name, like Search ⌘K.
When not to use
Section titled “When not to use”- For anything someone needs to finish a task. Tooltips don’t show on touch screens, so put it on the page.
- For a sentence or two of explanation, like what slippage means. Use a popover the reader opens with a click.
- For anything with a link or a button inside. A tooltip closes as soon as the pointer leaves.
- On a control that already shows its label, or on plain text that can’t be focused.
Anatomy
Section titled “Anatomy”- 1TriggerThe control it names, usually an Icon button.
- 2Label12px medium text on the inverse surface. A few words.
- 3HintOptional. A shortcut or status in a quieter grey.
Icon button
Section titled “Icon button”Every Icon button shows its label in a tooltip, so most screens never use Tooltip directly. Turn it off with tooltip={false} when the same words sit right beside the button, and move it with tooltipSide when the top is crowded.
Placement
Section titled “Placement”Tooltips open above the trigger by default, 8px away, with no arrow. They flip to the other side when there’s no room. Use side="right" on a left rail and side="bottom" for controls at the top of the screen.
The collapsed sidebar names each item and shows its shortcut.
hint adds a shortcut or a short status after the label, in color/text/inverse-muted-foreground. Write shortcuts the way the keys read: ⌘K, G then H.
Long labels
Section titled “Long labels”Past 240px the label wraps. If it wraps often, the label is too long.
Behaviour
Section titled “Behaviour”- Resting the pointer opens a tooltip after 400ms. The wait tells pausing from passing, so a pointer crossing the screen doesn’t flash labels on every control it touches.
- Once one is open, the next opens at once, and for 300ms after it closes. Sweeping along a toolbar never pays the wait twice.
- Keyboard focus opens it straight away: Tab, or arrow keys inside a toolbar. Focus from a click, or a dialog focusing its first control, doesn’t.
- Moving away closes it, and the 100ms fade gives the pointer time to cross the 8px gap onto it, so it stays open while the pointer is on it.
- A click closes it until the pointer leaves the trigger. Escape closes it without moving focus.
- The first tooltip fades in over 150ms, growing from 96% and 2px out of the trigger on a steep ease-out. It fades out in 100ms. While you sweep along a row, one bubble follows the pointer: the next tooltip starts where the last one was and glides to its button in 200ms, resizing to its label. It only glides on the same side and within 160px; further away, or when it flips side, it swaps in place.
- With reduced motion it only fades, with no scale, movement or glide.
| Key | Action |
|---|---|
| Tab | Moves focus to the trigger and shows its tooltip. |
| Arrow keys | In a toolbar that moves focus with arrows, shows the newly focused button’s tooltip. |
| Escape | Hides the tooltip and keeps focus on the trigger. |
When pointing is the task
Section titled “When pointing is the task”The wait protects people from controls they’re only passing. When someone points somewhere just to read the tooltip, like a point on a chart, a slider’s value while dragging, or a timeline while scrubbing, open it at once with delayDuration={0} on that Tooltip.
Content
Section titled “Content”- Name the action in a few words, in sentence case, with no full stop: Copy address, View on explorer.
- Use the same words as the control’s accessible name, so what people see is what screen readers say.
- Keep it under 240px. If a label wraps, it is probably an explanation.
Accessibility
Section titled “Accessibility”- The tooltip has
role="tooltip"and describes its trigger while it’s open. On an Icon button the text repeats the button’s name, so Icon button leaves the description off. - Screen readers and touch screens may never show it. The trigger needs its own accessible name.
- Tooltips mount at the end of the page, so a card’s
overflow: hiddennever clips them.
Tooltip wraps one trigger and its content. TooltipProvider sits at the root of the hub; a Tooltip outside it makes its own.
| Prop | Type | Default | Notes |
|---|---|---|---|
side |
"top" | "right" | "bottom" | "left" |
"top" |
On TooltipContent. Flips when there’s no room. |
sideOffset |
number |
8 |
On TooltipContent. The gap to the trigger. |
hint |
ReactNode |
On TooltipContent. Dimmed text after the label. |
|
container |
HTMLElement |
document.body |
On TooltipContent. Where the tooltip mounts. |
open, onOpenChange |
On Tooltip, to control it. open={false} keeps it shut. |
||
delayDuration |
number |
400 |
On TooltipProvider or Tooltip. 0 when pointing is the task. |
skipDelayDuration |
number |
300 |
On TooltipProvider. How long the next tooltip skips the wait. |
<Tooltip> <TooltipTrigger asChild> <button aria-label="Search">…</button> </TooltipTrigger> <TooltipContent side="right" hint="⌘K"> Search </TooltipContent></Tooltip>Related
Section titled “Related”- An Icon button shows its label in a tooltip.
- A Button shows its label all the time.