Components · Feedback & status

Tooltip

A short label that appears on hover or focus. It is the component most likely to be handed information it must not hold, because it is the easiest place to put something when a layout is full.

Stable · v1.0 shadcn/ui WCAG 2.2 AA SC 1.4.13

Overview

This system bans hover as a sole carrier of information — see Interaction states — which puts the tooltip in an awkward position. The resolution is not to forbid it, but to be exact about what it is for: a tooltip supplements something already visible. It never carries anything a clinician needs in order to act.

Roughly half the surfaces this system targets are touch-only, where hover does not exist at all. A tooltip on a cart display is not a degraded experience — it is nothing. Anything that would be lost there was never safe to put in a tooltip.

Supplementary

Removing every tooltip in the product must change nothing about what a clinician can do or decide. If it does, that content belongs on the page.

Reachable

Hover, keyboard focus and long-press all open it. A tooltip only a mouse can reach is unavailable to most of the people using it.

Brief

A few words naming a thing. A tooltip containing a sentence is a popover; one containing a decision is a defect.

Anatomy

Tooltip on an icon-only control
Compare with prior ECG
Acute coronary syndrome ACS

Both bubbles are shown open so they can be read here. In use they appear on hover, focus or long-press, one at a time.

ElementRule
Trigger An interactive control, or an <abbr>. Never a bare span — a tooltip on something unfocusable is unreachable by keyboard.
Bubble Inverse surface, one line where possible, 200 px maximum when wrapping.
Relationship aria-describedby. The control still carries its own accessible name via aria-label — the tooltip does not supply it.
A tooltip is not an accessible name

An icon-only button needs both an aria-label (so assistive technology and voice control can name it) and a tooltip (so a sighted user can discover what the glyph means). Using the tooltip as the label leaves the control unnamed for anyone not hovering it; using the label alone leaves a sighted clinician guessing at an icon under time pressure.

What must never go in a tooltip

NeverBecauseInstead
Units of a measurementThe value becomes unitless on touch and in print Permanent suffix or label — Text field
A confidence scoreReliance information must be visible at the moment of the decisionConfidence disclosure
Patient identifiersIdentity is never conditional on a pointer Patient header
An error or validation messageErrors must persist and be announced Inline error text with aria-describedby
The full text of a truncated clinical valueTruncation of clinical content is itself prohibitedWrap, reflow, or shorten the label
Anything needed to choose between two actionsDecisions are not made by hoveringVisible helper text, or a Dialog

What a tooltip is legitimately for

Why "nothing crucial" is not a usable rule

Almost every design system states some version of never put crucial information in a tooltip. It is correct, and it does not work — because "crucial" is undecidable at design time and everybody believes their case is the exception.

The usual evidence is on the same pages that state it. A widely-used system publishes the rule and then recommends tooltips for truncated text, for defining terms, for alternative text on images, and for the values behind a chart. Each of those is defensible in isolation. Together they are four routes to putting something load-bearing behind a pointer, on a page whose own rule forbids exactly that.

The decidable test

Remove every tooltip in the product. Does anything change about what a clinician can do or decide? If yes, that content belongs on the page. The question has one answer, it can be asked of a design before it is built, and it does not depend on anyone's judgement about importance.

The four that look reasonable

Revealing truncated text

The most common recommendation and the one this system has least room for, because truncating clinical content is itself prohibited. A tooltip here is a second defect covering for a first: the text is clipped, and the only complete copy is behind a pointer that half our surfaces do not have. Wrap, widen, or shorten the label.

Defining a term

Legitimate for an abbreviation whose expansion is a convenience — "ACS" for a reader who already knows what it stands for. Not legitimate for a definition the reader needs in order to act, which is most definitions worth writing. The test above settles it: if removing the tooltip changes what they can decide, the expansion belongs in the text on first use.

Alternative text for an image

This one is not a judgement call — it is simply wrong. A tooltip is not alternative text. Assistive technology reads the alt attribute; a title or a hover bubble is not a substitute and is inconsistently announced. An image whose description lives in a tooltip has no description for the reader who most needs one, and the recommendation inverts the accessibility it appears to serve.

The values behind a chart

The most defensible of the four, which makes it the most dangerous. Hover-to-read is the near-universal convention for charts, and it puts the numbers — the actual data — behind a pointer.

The pattern under all four

Each begins with a real layout problem — text too long, a term unfamiliar, an image without words, a chart too dense to label. The tooltip solves the layout problem and moves the information somewhere half the readers cannot reach. It is a container that makes a design look finished without being finished, which is why it is the component most often handed things it must not hold.

Behaviour

WCAG 2.2 SC 1.4.13 sets three requirements for content shown on hover or focus, and all three are met by the component rather than by each call site.

RequirementImplementation
Dismissible Esc closes without moving the pointer or focus.
Hoverable The pointer can travel into the bubble without it closing — so a magnified user can reach content that overlaps their cursor.
Persistent Stays until dismissed, focus moves, or the pointer leaves. Never auto-hides on a timer.

Writing it

Do
Acknowledge alarm

Names the action. The button is independently labelled, so nothing is lost on a touch display.

Don't
47 ng/L · conf 0.71 · v4.2 47

Unit, confidence and model version behind a hover. On a cart display this is the number 47, unqualified, in a clinical record.

What the component enforces, and what it only asks for

All three of the WCAG 1.4.13 behaviours are held here, which was not true until a browser was pointed at them. What is not held is whether the tooltip should exist at all.

RuleHeld by How
Dismissible without moving the pointerThe component Escape closes it — one of three behaviours this page claimed and none of which existed before the interaction gate.
Asserted: Tooltip: Escape dismisses it — SC 1.4.13, dismissible
HoverableThe component The pointer handlers are on the wrapper, so moving onto the tooltip does not dismiss it.
Asserted: Tooltip: the bubble is hoverable — SC 1.4.13
Persistent while hovered or focusedThe component No timeout. It closes when the pointer or focus leaves, and not before.
Asserted: Tooltip: stays open while hovered, with no timeout of its own
Opens on focus without the hover delayThe component 400 ms on hover, immediate on focus, so a keyboard user is not made to wait.
Asserted: Tooltip: opens after a delay on hover, instantly on focus
It adds to a control’s description rather than replacing itThe component The tip’s id is appended to the control’s own aria-describedby, and the control’s own focus handlers still run. It replaced both: wrapping a field in a tooltip deleted its hint, and while the tip was closed deleted it entirely. Read from the accessibility tree.
Asserted: Tooltip: it adds to a control's description, and keeps the control's own
It never carries the name of its controlYou content is a string. A tooltip repeating the accessible name is invisible to the reader who most needs it, and only you can see that you have done it.
Nothing clinical lives only hereYou A tooltip is supplementary by rule, not by construction. Nothing stops you putting a reference range in one, where no touch user will find it.
Why this is written down

A rule stated on a component page reads as a rule the component keeps. 4 of these 6 are; 2 are obligations this page was quietly handing to the reader. Conformance is held; editorial judgement is not. A tooltip that duplicates its label passes every check on this page and helps nobody.

Do's and don'ts

Do
Acknowledge alarm

Tooltip and aria-label both present. Nothing is lost on a touch display.

Don't
Acknowledge alarm

The tooltip used as the accessible name. Voice control and screen readers have nothing to call this button.

Do
hs-troponin ng/L

14 → 47 → 112
14:26 · 15:26 · 16:26

The values are on the page. A hover readout may sit on top of this as an accelerator; it is not how the numbers are reached.

Don't
hs-troponin hover a point for values

A line, three unlabelled points.

The data is behind a pointer. On a cart the trend has a shape and no numbers, and nobody can quote it.

Do

Acute coronary syndrome (ACS) was not excluded by the 0/1 h algorithm.

Expanded on first use, in the text. The reader needs it to follow the sentence, so it is in the sentence.

Don't

ACS was not excluded by the 0/1 h algorithm.

The expansion is available to a reader with a pointer who thinks to hover. Everyone else reads three letters.

Do

<img alt="12-lead ECG, anterior ST elevation in V2–V4">

The description is in the attribute assistive technology reads.

Don't

<img title="12-lead ECG, anterior ST elevation in V2–V4">

A tooltip is not alternative text. The image now has no description for the reader who most needs one, and the recommendation inverts the accessibility it appears to serve.

Accessibility

Outcomes of use

What this contributes to, in the terms of Usability & context of use. These are attributes believed to contribute to an outcome; the outcome itself is settled by observing real use in a specified context, not by this page.

Clinical safety notes

Risk controls this page specifies

Trace these in your risk file (ISO 14971) and usability engineering file (IEC 62366-1). Which of these the component keeps and which are yours is stated in the guarantees table; a control the component does not keep is one your risk file must show you keep.

Implementation

$ npx shadcn@latest add https://md.notjustany.tech/r/tooltip.json
<Tooltip content="Opens the prior study alongside this one">
  <Button variant="outline">Compare with prior</Button>
</Tooltip>

// The trigger is a labelled button, not an icon: this package has no icon
// set, and a tooltip may not carry the name of the control it sits on.
// Hover opens after 400 ms, focus opens at once, Escape closes, and the
// surface is hoverable — SC 1.4.13.

What the component takes. This table used to list openDelay, side — props the component does not have, and never had. Found by the registry gate’s props-table rule.

PropTypeDefaultNotes
contentstring— Plain text only. Rich content means you wanted a Dialog or popover.
childrenReact.ReactElement— Required. The control it describes. Its own name and description are kept.
NotJustAnyMed.Tech Design System · Tooltip · v1.0 · draft for review
Reference applications named in this system are fictional; all patient data shown is fabricated.