Designer view

Tooltip

A non-interactive floating panel that surfaces brief descriptive text about its trigger, revealed on hover or focus and dismissed on blur, pointer-leave, or Escape. Distinct from Popover (interactive) and Modal (blocking): tooltip content is read-only, the user never enters the tooltip, and Tab moves past the trigger without entering the tooltip body. Used for icon labels, abbreviation expansions, short helper text — never for essential information.

When to use

Use

When a control's accessible name benefits from a brief supplementary description that does not need to be permanently visible — icon-only buttons, abbreviations, status badges, column headers in dense tables. The description is non-essential (the control operates correctly without it) and short (one or two sentences).

Avoid

For interactive content (buttons, links, forms inside the floating surface) — that is `Popover`. For essential information that defines the control — that belongs in the accessible name (`aria-label`, visible text). For paragraph-length explanations — that is body prose or a Disclosure. For status messages that announce state changes — that is `Toast` or a `aria-live` region.

Versus related

  • popover

    `Popover` is interactive — the user may tab into the body and click controls. `Tooltip` is non-interactive — focus never enters the tooltip, and the body must contain only descriptive text. The boundary is canonical and APG- defined; do not blur it with "tooltip with a button" designs.

  • modal

    `Modal` is blocking and viewport-centred; `Tooltip` is non-blocking and trigger-anchored. They occupy opposite ends of the floating-surface spectrum (Modal: maximum modality, content-rich; Tooltip: zero modality, description-only).

  • alert

    `Alert` is an inline `aria-live` message announcing state changes; `Tooltip` is on-demand description revealed by hover or focus. Alert pushes content at the user; Tooltip is pulled by the user's interaction.

Highlight
Fig 1.1 · Tooltip · Designer view
Designer

Figma anatomy

Slot Figma type Hint
trigger instance Consumer-provided trigger; in Figma the Tooltip frame is anchored to but does not contain the trigger
container frame Floating frame with optional tip; max-inline-size cap
arrow rectangle 6×6 triangle clipped from a rotated square
Designer

Token usage per slot

container
spacing
  • paddingspacing.tight
radius
  • cornerradius.sm
color
  • backgroundcolor.surface.sunken
  • foregroundcolor.text.primary
  • bordercolor.border.subtle
elevation
  • shadowelevation.md
typography
  • sizetext.sm
  • lineHeightleading.snug
arrow
color
  • backgroundcolor.surface.sunken
  • bordercolor.border.subtle
Both

Figma ↔ Code property map

FigmaTypeCodeNotes
VariantVariantvariantMaps standard / inline-help.
SideVariantsidetop / right / bottom / left. Authored placement preference; auto-flips when colliding with viewport.
AlignVariantalignstart / center / end along the perpendicular axis.
DelayVariantdelayinstant / short / base / long. Maps to library-specific milliseconds (Radix uses 0/200/700/1500 by default).
Has ArrowBooleanarrowToggles the arrow slot. True by default for standard variant; false for inline-help.
ContentTextchildrenThe tooltip text. Capped at one to two short sentences by canon.
Designer

Motion

TransitionDuration token
openmotion.duration.fast
closemotion.duration.instant
Easing
motion.easing.decelerate
Reduced motion
Instant (jump cut)
Designer

Responsive behaviour

BreakpointChange
breakpoint.smAt and below, hover-driven tooltips are unreliable because most touch devices do not surface persistent hover events. The canonical fallback is long-press (~500ms) plus focus on tap-and-hold; some implementations replace tooltip with a contextual Popover triggered on tap. Inline-help variant switches to tap-to-toggle automatically (the icon becomes a button with aria-haspopup).
breakpoint.mdAbove this width, hover and focus reveal as authored. The floating positioning honours `side` and `align`; auto-flip and shift work as designed.
Both

Internationalisation

RTL · mirroring

Side property is direction-neutral (top/right/bottom/left are physical). Align is logical (start/center/end follow inline direction). Tooltip text inherits document direction; mixed-direction text (Arabic content with English code snippets in the tooltip) follows the inner spans' `dir` attributes. Auto-flip is symmetric across directions. Arrow glyph is a triangle — direction-neutral.

Text expansion

Tooltip text expansion is constrained by the canonical max-inline-size (commonly 240–320px). Long-text languages (German, Russian, Finnish) may wrap to two or three lines; above three lines, the canonical mistake `tooltip-paragraph- length` applies — the content belongs in a Popover or body prose. Allow soft-wrap; never truncate with ellipsis (the truncated description loses meaning).

Both

Variants, properties, states

Variants

Structurally different versions of the component.

standardinline-help

Properties

The same component, parameterised.

PropertyType
sidetop | right | bottom | left
alignstart | center | end
delayinstant | short | base | long
arrowboolean

States

Browser/user-driven (interactive) vs. app-driven (data).

KindStates
interactive
hoverfocus-visible
data
closedopeningopenclosing
Both

State transitions

FromToTrigger
closedopeningPointer enters the trigger or focus moves to the trigger. The configured delay timer starts; the tooltip is not yet visually revealed.
openingopenThe delay timer completes (or, under prefers-reduced-motion reduce, the tooltip appears immediately at the canonical instant fallback). aria-describedby is wired and the SR-announceable description is present.
openclosingPointer leaves the trigger AND focus is not on the trigger; or focus leaves the trigger AND pointer is not over it; or the user presses Escape to dismiss persistently. The canonical OR-conjunction prevents flicker when the user moves focus while hovering.
closingclosedThe exit animation completes (or immediately under reduced motion). aria-describedby remains on the trigger but the container is removed from the DOM (or hidden via CSS).
Both

Figma↔Code mismatches

  1. 01
    Figma

    A tooltip drawn with a button inside ("Got it" or "Learn more")

    Code

    A tooltip with role=tooltip, which APG forbids interactive content

    Consequence

    Designers may treat tooltip as a small popover and add dismiss buttons or links. Implementations that follow the Figma file create something with `role="tooltip"` plus a button — SR users cannot reach the button (focus does not enter tooltips), and the visual affordance suggests interaction that does not work. The pattern collapses to Popover.

    Correct

    Treat the boundary as canonical: tooltips contain only non-interactive content. If the surface needs a dismiss button or any interaction, redesign as a Popover. Document this distinction prominently in the canonical reference and in `whenToUse`.

  2. 02
    Figma

    A tooltip drawn that only appears on hover

    Code

    A tooltip that fires on hover but not on focus

    Consequence

    Designers think tooltips are a hover affordance; developers shipping hover-only break keyboard accessibility — keyboard users tab to the trigger but never see the description. Touch devices fall back to long-press; without focus-trigger they have no canonical reveal at all on touch keyboards.

    Correct

    Tooltip MUST trigger on both pointer-enter and focus. Document this as a non-negotiable a11y rule in the canonical reference. Touch devices use long-press by convention; the reveal happens via the same focus event pattern when the trigger is focusable.

  3. 03
    Figma

    Tooltip drawn carrying essential information

    Code

    Tooltip used as the primary descriptor for a control

    Consequence

    Designers may use tooltip text as the only descriptor for icon-only controls; developers shipping this lose the description for SR users (who hear the icon's `aria-label` only) and for users on slow connections (who may not see the tooltip render before activating). The essential information is locked behind a hover-only reveal.

    Correct

    Essential information is in the trigger's accessible name (`aria-label`, visible text, etc.), never in the tooltip. The tooltip supplements with details that are useful but not required to operate the control. Document the canonical contract: tooltip is supplementary description, not primary label.

  4. 04
    Figma

    A tooltip drawn pointing at a passive area (a label, a static word)

    Code

    A tooltip wired to a non-focusable element with `aria-describedby`

    Consequence

    Designers anchor tooltips to non-interactive surfaces; developers wire them with no focus-trigger because the element is not focusable. Keyboard users miss the tooltip entirely; pointer users see it on hover but the experience is incomplete.

    Correct

    If the element needs a tooltip, it must be focusable — either it's already an interactive control, or wrap it in a focusable element (a button, a `<dfn>` or `<abbr>` with `tabindex="0"`). The tooltip's reveal contract requires both pointer and keyboard reachability.

Designer

Common mistakes

#tooltip-with-interactive-content

Tooltip containing buttons or links

Problem

The tooltip body has interactive elements (a "Learn more" link, a "Got it" button). APG forbids this — tooltip content is non-interactive, focus does not enter the tooltip, and SR users cannot reach the interactive children.

Fix

If the surface needs interaction, use a Popover. The distinction is canonical: Tooltip = non-interactive descriptive text; Popover = interactive contextual content. No "tooltip with a button" middle ground.

#tooltip-no-focus-trigger

Tooltip only reveals on pointer hover

Problem

The tooltip fires on `mouseenter` but not on `focus` events. Keyboard users tab to the trigger; the tooltip never appears. Touch devices that surface the focus event also lose the tooltip.

Fix

Always pair pointer-enter with focus-enter as reveal triggers, and pointer-leave with focus-leave as dismiss triggers (with the OR-conjunction documented in the transitions block — tooltip stays open while either pointer or focus remains).

#tooltip-essential-info

Essential information in tooltip

Problem

The tooltip text is the only descriptor for an icon-only control. SR users who skip the tooltip via verbose-mode-off get just the icon's `aria-label`; pointer users on slow connections may activate before the tooltip renders.

Fix

Essential info goes in the trigger's accessible name. The tooltip supplements with non-essential details. The test: remove the tooltip — does the control still operate correctly with full meaning? If no, the tooltip held essential info that belongs in the label.

#tooltip-paragraph-length

Tooltip with multi-paragraph content

Problem

The tooltip body grows beyond a brief sentence — multiple sentences, lists, or paragraph-length prose. Hover dismisses while the user is reading; SR description fires the entire paragraph as one announcement.

Fix

Cap tooltip content at one or two short sentences. Anything longer should live in body prose, a Popover, or a Disclosure. Document the canonical length convention and enforce it in design review.

#tooltip-pointer-events-block

Tooltip captures pointer events from underlying content

Problem

The tooltip's container has `pointer-events: auto` — the user's mouse enters the tooltip area on its way to another control, the tooltip blocks the click, and the trigger cannot be reached again. Or worse, the tooltip itself becomes hoverable and traps the cursor in a hover loop.

Fix

Tooltip container has `pointer-events: none` by default. The tooltip is a non-interactive overlay that text can be read from but not clicked into. Pointer events pass through to the underlying content. The trigger handles all hover logic; the container is purely visual.

Accessibility hints
Slot Accessibility hint
trigger Trigger element carries `aria-describedby` referencing the tooltip container's id (NOT `aria-labelledby` — the tooltip is supplementary description, not the accessible name). For triggers without their own accessible name (e.g. an IconButton), the tooltip text duplicates as the `aria-label` plus the `aria-describedby` reference, so SR users hear the label first then the description.
container Apply `role="tooltip"`. The container has no interactive children — buttons, links, form controls inside a tooltip violate the APG contract. Sized to text; do not host layouts. The container does NOT receive focus; tabindex is absent.
arrow Decorative; do not put `role` on it. The trigger-to-tooltip relationship is communicated by `aria-describedby`, not by the arrow.