Tooltip
Tooltip — a few words on hover or focus that name the thing under the pointer.
Beta · Feedback and status · packages/css/src/components/tooltip.css
.pui-tooltip · side --bottom --left --right (top is the default). A few words; a sentence is a Popover.
Sizes across, states down.
What it is for
Section titled “What it is for”- Side: top, bottom, left, right — where the tooltip sits relative to its trigger; the arrow points at the trigger
- Label is a text property; keep it to a few words — a sentence is a Popover
- No states: the trigger has hover and focus, the tooltip only appears
- Motion: fade and zoom from 95% on open, motion/state (150ms)
Use when an icon button needs its name, a truncated cell needs its full value, a control needs one line of help.
Do not use when the information is needed to complete the task (put it in the UI); it holds a link or a button (Popover); it explains an error (Field’s error, Alert); on touch, where hover does not exist — the name must also be readable another way.
Relates to Icon button (its label), Popover, Hover card (rich preview), Field (helper text).
Anti-patterns a tooltip on plain text · a tooltip that repeats the visible label · more than two lines · a tooltip as the only accessible name.
Keywords: tooltip, hint, hover, label, help
Figma — page Tooltip: Tooltip (4 variants)
shadcn: tooltip
The markup — copy this
Section titled “The markup — copy this”The class, the parts, and nothing that is not in the package. The same block opens tooltip.css.
<div class="pui-tooltip pui-tooltip--top" role="tooltip">Copy link</div>The modifiers
Section titled “The modifiers”| What it is | Note | |
|---|---|---|
| Side | (none) top · --bottom · --left · --right — where the tooltip sits; the arrow points at the trigger | — |
Rule — a few words; a sentence is a Popover. Placing it is the code side’s; this file draws it.
Accessibility — measured, not assumed
Section titled “Accessibility — measured, not assumed”Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.
Contrast
Section titled “Contrast”| ink on ground | reads | floor | the matrix calls it | |
|---|---|---|---|---|
#ffffff on #231b1b |
16.88 | 4.5 | text.on-accent on surface.inverse (not-offered) | ok |
1 distinct pair(s) rendered, 0 that axe calls a violation.
The focus ring
Section titled “The focus ring”Nothing in this component takes focus.
Keyboard
Section titled “Keyboard”| role | tab stops | what the pattern requires | |
|---|---|---|---|
tooltip .pui-tooltip |
0 | — | — |
tooltip .pui-tooltip.pui-tooltip--bottom |
0 | — | — |
tooltip .pui-tooltip.pui-tooltip--left |
0 | — | — |
tooltip .pui-tooltip.pui-tooltip--right |
0 | — | — |
tooltip .pui-tooltip |
0 | — | — |
What the consumer’s script owes. it appears on FOCUS as well as hover, stays while the pointer is over it, and Escape dismisses it without moving focus — WCAG 1.4.13 Content on Hover or Focus.
Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).
Pepper UI v1.5.0
The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.