Skip to content

Tooltip

A short hint for an element, on hover and keyboard focus. Light or dark, with an optional title and beak, and a placement that mirrors in RTL.

Version 0.4.1 ·

Placements

Installation

bunx --bun shadcn@latest add @dga/tooltip

Usage

page.tsx
tsx
import { Button } from "@/components/ui/button";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";

export function SaveHint() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger render={<Button variant="outline" />}>Drafts</TooltipTrigger>
        <TooltipContent side="end" title="Drafts">Opens your saved drafts.</TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}

Use a Tooltip to name an icon-only button or to add a short hint to a control. Keep it to a sentence. It is a hint for sighted mouse and keyboard users, not the place for links, buttons or anything people must read: screen readers and touch screens do not rely on it. Wrap the app or a toolbar in a TooltipProvider so the second tooltip opens at once while the pointer moves along. For the question-mark that explains a label, use TooltipHelp: it opens on click and touch too and can be read by a screen reader.

Anatomy

  • Trigger: the element it describes. Any button, link or input.
  • Bubble: at most 240px (at least 160px), radius-xs, shadow-lg.
  • Title (optional): bold, above the text.
  • Beak: the 14px point toward the trigger. Turn it off with showArrow={false}.
  • Help Icon: TooltipHelp, a 20px question-mark button that opens the same bubble as a popover.

Examples

Tones

tone is light (white) or dark (the inverted tooltip). In dark mode they swap. Hover or focus the buttons.

Tones

Help icon

TooltipHelp next to a label. It is a real button with an accessible name that opens on hover, focus, click and touch, so keyboard, touch and screen reader users reach the text.

Help icon

Arrow, title and disabled

A tooltip opens on hover and on keyboard focus, and closes on blur, Escape or when the pointer leaves. showArrow={false} drops the arrow, a title adds a bold first line for longer text, and disabled on Tooltip turns it off while keeping the trigger.

Arrow, title and disabled

RTL

side takes start and end as well as top and bottom. They are the sides of the text, so end opens to the left on Arabic pages, and the beak follows. align="start" lines up with the right edge of the trigger in RTL.

LTR (English)
RTL (Arabic)

Accessibility

KeyAction
TabFocusing the trigger opens the tooltip. Moving away closes it.
EscapeCloses the tooltip without moving focus.
EnterOn a Help Icon, opens the explanation (and closes it again).
  • A Tooltip is for sighted mouse and keyboard users (Base UI says the same): put anything important in the page text. An icon-only trigger needs an aria-label, because the tooltip does not name it.
  • TooltipHelp is a popover, so it also opens on click, Enter and touch, is announced as a dialog-like popup with its title and text, and closes with Escape. It has an accessible name (label).
  • It opens on keyboard focus as well as hover, stays open while the pointer is over the bubble, and closes with Escape (WCAG 1.4.13: dismissible, hoverable, persistent).
  • Text is 4.5:1 or better on both tones, light and dark. The Help Icon is 3:1 or better on every surface and has a focus ring.
  • The bubble fades in; with reduced motion it appears without animation.

API Reference

Tooltip

A short hint for an element, shown on hover and on keyboard focus (DGA: Tooltip). Tooltips are for sighted mouse and keyboard users: screen readers and touch screens do not rely on them, so they never hold the only copy of something people need, and they are not for interactive content. An icon-only trigger still needs an `aria-label`.

Tooltip props
PropTypeDefault
boolean

Whether the tooltip is currently open.

No default
boolean

Whether the tooltip is initially open. To render a controlled tooltip, use the `open` prop instead.

No default
boolean

Whether the tooltip is disabled.

No default

Also accepts every prop of the Base UI Popover (opens in a new tab).

TooltipContent

The bubble. It is at most 240px wide and keeps clear of the screen edges.

TooltipContent props
PropTypeDefault
"light" | "dark"

`light` is white (neutral-800 in dark mode); `dark` is the inverted tooltip.

"light"
string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<AwaitedReactNode>

A bold heading above the text.

No default
"top" | "bottom" | "start" | "end"

Where it opens. `start` and `end` are the sides of the text, so they swap on Arabic pages.

"top"
boolean

Shows the beak that points to the trigger.

true

Also accepts every prop of the Base UI Popover (opens in a new tab).

TooltipHelp

The DGA Help Icon: a 20px question-mark button next to a label, with an explanation in the same bubble as a Tooltip. It is a Popover that also opens on hover, not a Tooltip: the button exists to show the text, so keyboard, touch and screen reader users must be able to open and read it too.

TooltipHelp props
PropTypeDefault
"light" | "dark"

`light` is white (neutral-800 in dark mode); `dark` is the inverted tooltip.

"light"
string

Accessible name of the icon button. Translate it on Arabic pages.

"More information"
string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<AwaitedReactNode>

A bold heading above the text.

No default
"top" | "bottom" | "start" | "end"

Where it opens. `start` and `end` are the sides of the text, so they swap on Arabic pages.

"top"
string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<AwaitedReactNode>

The explanation. It opens on hover, focus, click and touch, and screen readers can read it.

No default

Also accepts every prop of the Base UI Popover (opens in a new tab).

TooltipProvider

Sets how long people hover before a tooltip opens, and lets the next one open at once while they move between triggers. Wrap the page or a toolbar with it.

TooltipProvider props
PropTypeDefault
number

How long to wait before opening the tooltip on hover. Specified in milliseconds.

300

Also accepts every prop of the Base UI Popover (opens in a new tab).

TooltipTrigger

The element the tooltip describes. Render your own button or link with `render`.

Also accepts every prop of the Base UI Popover (opens in a new tab).

Deviations from DGA

  • DGA draws the placement with a physical 14px margin per direction. Here start and end are logical, so they swap in Arabic and the beak follows.
  • It also opens on keyboard focus. The Help Icon is built as a popover that opens on hover, so touch and screen reader users can read it too; Figma shows hover only.
ChangeReason
Tooltip: placement and behaviourA tooltip that shows only on hover is invisible to keyboard users, and a physical margin would sit on the wrong side in RTL. Base UI also advises that an info icon whose purpose is to show the text be a popover, so touch and screen reader users can read it.

View all 1 deviations for this component

Contrast

26 pairs checked · all pass WCAG 2.1 AAShow 7 states
Variant / stateLightDark
light / heading14.53:1 AAA14.42:1 AAA
light / text10.17:1 AAA10.95:1 AAA
dark / heading13.91:1 AAA14.00:1 AAA
dark / text13.20:1 AAA10.57:1 AAA
help icon4.57:1 3:19.38:1 3:1
help icon, hovered and open17.31:1 3:115.87:1 3:1
focus ring17.31:1 3:117.49:1 3:1

Text needs 4.5:1, icons and focus rings 3:1. Disabled states are exempt. Full contrast report