Skip to content

Tooltip

Shows a short hint about a control while it has hover or keyboard focus.

Library
What’s this?

Installation

pnpm dlx shadcn@latest add @wisty/tooltip

The CLI installs the Radix or Base UI file to match your project.

If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.

When to use

Use it

  • A control needs a short hint in plain text, like what an icon button does or what a field expects.
  • Field-level help: an info button beside a label, as Salesforce shows on record forms.

Don't use it

  • The content has links, buttons or fields, or more than a sentence or two. Use Popover, or Hover Card for a preview.
  • The information is needed to finish the task. Put it on the page, in the label or in a description below the field.
  • The control has no name of its own. Give it a visible label or an aria-label first. A tooltip isn't a name.
  • On touch screens, where there's no hover. Don't hide anything people need behind a tooltip.

Usage

TooltipProvider
└── Tooltip
    ├── TooltipTrigger
    └── TooltipContent

Put one TooltipProvider near the root of the app, around every Tooltip. In Radix projects a tooltip throws without it. In Base UI projects it works without one, but waits its own delay before opening.

import { buttonVariants } from "@/components/ui/button"
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger,
} from "@/components/ui/tooltip"
<Tooltip>
  <TooltipTrigger className={buttonVariants({ variant: "outline" })}>
    Freeze column
  </TooltipTrigger>
  <TooltipContent>Keeps this column in view as you scroll.</TooltipContent>
</Tooltip>

Examples

On an icon button

Icon buttons carry their name in `aria-label`, and the tooltip shows the same words to people who can see the icon.

Sides

Tooltips on each side of their buttons, set with `side` on `TooltipContent`.

API reference

PartBuilt on
TooltipProviderRadix Tooltip.Provider (opens in a new tab)
TooltipRadix Tooltip.Root (opens in a new tab)
TooltipTriggerRadix Tooltip.Trigger (opens in a new tab)
TooltipContentRadix Tooltip.Content (opens in a new tab)

TooltipProvider

PropTypeDefaultDescription
delayDurationnumber0The duration from when the pointer enters the trigger until the tooltip gets opened.

TooltipContent

PropTypeDefault
sideOffsetnumber0

SLDS mapping

  • TooltipContent is slds-popover slds-popover_tooltip and its slds-popover__body in one element.
  • Its arrow is SLDS's nubbin (slds-nubbin_*), centered on the edge that faces the trigger.
  • TooltipTrigger has no SLDS class of its own.

Known gaps:

  • No corner nubbins (slds-nubbin_bottom-left and others), and no error or warning tooltips.
  • The nubbin's shadow is SLDS's bottom-nubbin shadow, turned to point outward on every side. SLDS's own shadows for the other sides differ slightly.

Accessibility

  • Give every trigger a name of its own: its text, or an aria-label on an icon button, as the On an icon button example does. In Base UI projects nothing links the trigger to its tooltip, so screen readers don't read the tooltip at all.
  • Don't put anything in a tooltip that people can't get another way.
  • When the tooltip repeats an icon button's aria-label, some screen readers read it twice, once as the name and once as the description.

Motion

  • The tooltip fades over 0.1s in every theme. In Base UI projects it fades out too; in Radix projects it disappears at once. The fade only changes opacity, so it stays on with reduced motion.

Rules

  • Never nest a Button inside TooltipTrigger. That's a button in a button; style the trigger with buttonVariants() instead.
  • Keep tooltip text short and plain: no links, buttons or headings.
  • Don't style TooltipContent's colors, padding or nubbin. They come from the theme.