Azalea

Tooltip

A short explanation, on hover and on focus.

No JavaScript, deliberately

A tooltip is the component most often built as a portal with a positioning library. The version that costs nothing does the same job here: CSS shows it on :hover and on :focus-within, so it works before hydration, inside a server component, and with a keyboard. Tab to the button below without touching the mouse.

Retries the run from the failed step, keeping its inputs.COMPLAINEDDelivered, then the recipient marked it as spam.

Why not title=""

The native attribute waits about a second, cannot be styled, is announced inconsistently across screen readers, and never appears for a keyboard user at all. The one thing it still does better is survive on touch, where nothing hovers — which is the real limit here.

Nesting the bubble inside a button would fold its text into the button's accessible name, and the control ends up announced as its own explanation: “Retry, retries the run from the failed step, keeping its inputs, button”.

In both themes

light

Same bubble, both grounds.

dark

Same bubble, both grounds.

Guidance

Use it when

  • A hint that is nice to have: what an abbreviation stands for, what a status means, what a button will do.
  • On an icon-only control, alongside — never instead of — its aria-label.
  • Short. One line. This is a hint, not documentation.

Reach for something else when

  • Anything that must be read. Nothing hovers on a phone, so a tooltip on touch is content nobody sees.
  • Interactive content. There is no way to move the pointer into this bubble without leaving the trigger.
  • A form field's requirements. That is Field's hint, which is wired with aria-describedby and always visible.

Props

PropTypeDefaultDescription
contentReactNodeThe hint. One line.
side"top" | "bottom""top"Which way it opens. Two options on purpose — anything cleverer needs measuring, and measuring needs JavaScript.
childrenReactNodeThe trigger. Must be focusable for the keyboard half to work.

Accessibility

The bubble is role="tooltip" and the trigger points at it with aria-describedby, so it is announced as a description rather than as part of the name. It is hidden with opacity rather than display: none — a display-toggled tooltip is skipped by some screen readers even when aria-describedby points straight at it. And :focus-within is what makes tabbing to the trigger enough: a hover-only tooltip is invisible to anyone navigating by keyboard, which in a console is a large share of the people using it.