Browse the docs

Tooltip

Supplementary label shown on hover and on keyboard focus. It is CSS only — no positioning library, no state, and it renders in a server component.

Runs the last successful build againCopied to your clipboard as JSONThis cannot be undone, and the domain is released immediately.

Props

PropValuesDefaultDescription
contentnodeWhat the bubble says.
side"top", "bottom", "left", "right""top"Which side of the trigger it sits on.
idstringPut the same value in the trigger's aria-describedby.
classNamestring""Applied to the wrapper, not to the bubble.

children is the trigger. It must be focusable for the tooltip to be reachable by keyboard — a <button> or a link, not a <span>.

Common patterns

// The usual case
<Tooltip content="Runs the last successful build again">
  <Button variant="outline">Redeploy</Button>
</Tooltip>

// Associated as a description, so a screen reader reads it too
<Tooltip id="delete-tip" content="This cannot be undone.">
  <Button variant="danger" aria-describedby="delete-tip">Delete</Button>
</Tooltip>

// An icon-only trigger still needs its own name
<Tooltip content="Copy to clipboard" side="right">
  <Button variant="ghost" aria-label="Copy to clipboard">
    <CopyIcon />
  </Button>
</Tooltip>

Notes

A tooltip is never the only label. The bubble is not read by default, so an icon-only button that relies on it has no accessible name at all. Give the trigger aria-label, then add the tooltip on top for sighted users.

It does not flip. Having no JavaScript means nothing measures the viewport, so a side="top" tooltip near the top edge is clipped. Choose the side that has room — in a toolbar pinned to the top, that is bottom.

It does not appear on touch. There is no hover on a touchscreen, and tap does not focus. Anything a phone user must know belongs in visible text.

If you need flipping and collision detection, that is a positioning problem rather than a styling one, and it needs real measurement code. This component is deliberately the small version.