Tooltip
An accessible tooltip on Base UI's positioning engine, with hover/focus triggers and reduced-motion-aware animation.
Real use · sides (hover or focus a trigger)
Grouped delay (adjacent tooltips open instantly)
Using Tooltip
Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.
Plain HTML — CSS classes
The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path ships no JavaScript, so Tooltip is styled but inert: its behavior comes from popover. For that behavior with no framework, use the node-tree path below.
/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";Root class tooltip, with 1 modifier:
.tooltip.tooltip-arrow
React
Typed components over those same classes, with behavior and accessibility from Base UI.
npm i @wizeworks/silicaui-reactimport { Tooltip } from "@wizeworks/silicaui-react";Props
| Prop | Type | Required | Description |
|---|---|---|---|
| content | React.ReactNode | yes | The floating content. |
| children | React.ReactElement | yes | The trigger element — Base UI merges hover/focus behavior onto it. |
| side | TooltipSide | no | Which side of the trigger to prefer. Default top (flips to avoid collisions). |
| align | TooltipAlign | no | Alignment along that side. Default center. |
| sideOffset | number | no | Gap between trigger and popup, in px. Default 8. |
| delay | number | no | Hover-open delay in ms. Default 600 (Base UI). |
| closeDelay | number | no | Close delay in ms. Default 0. |
| open | boolean | no | Controlled open state. |
| defaultOpen | boolean | no | Uncontrolled initial open state. |
| onOpenChange | (open: boolean) => void | no | — |
| disabled | boolean | no | Disable the tooltip entirely. |
| arrow | boolean | no | Show the little arrow. Default true. |
| className | string | no | Extra class on the popup surface. |
| popupProps | React.ComponentProps<typeof BaseTooltip.Popup> & { [key: `data-${string}`]: string | undefined; } | no | Props forwarded to the popup surface itself. |
| anchor | BasePositionerProps["anchor"] | no | What to position against. Defaults to the component's own trigger. |
| positionMethod | BasePositionerProps["positionMethod"] | no | absolute (default) or fixed. Use fixed to escape a clipping ancestor. |
| alignOffset | BasePositionerProps["alignOffset"] | no | Offset along the alignment axis, in px. Pairs with align. |
| collisionBoundary | BasePositionerProps["collisionBoundary"] | no | The element the popup must stay inside. Defaults to the viewport — set it to a scroll container so the popup collides with the panel, not the window. |
| collisionPadding | BasePositionerProps["collisionPadding"] | no | Inset from the collision boundary, in px. |
| collisionAvoidance | BasePositionerProps["collisionAvoidance"] | no | Which collision strategy runs per axis (flip, shift, none). |
| sticky | BasePositionerProps["sticky"] | no | Keep the popup glued to the anchor while it scrolls out of view. |
| arrowPadding | BasePositionerProps["arrowPadding"] | no | Minimum distance from the popup's corner to the arrow, in px. |
| disableAnchorTracking | BasePositionerProps["disableAnchorTracking"] | no | Stop re-measuring when the anchor moves. Cheaper, but goes stale. |
Source of the demo above
The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.
Show source
import { Tooltip, TooltipProvider, Button } from "@wizeworks/silicaui-react";
import { Section, Row } from "../lib/Section";
export function TooltipDemo() {
return (
<TooltipProvider>
<Section title="Real use · sides (hover or focus a trigger)">
<Row>
{(["top", "right", "bottom", "left"] as const).map((side) => (
<Tooltip key={side} content={`On the ${side}`} side={side}>
<Button variant="outline" color="neutral">
{side}
</Button>
</Tooltip>
))}
</Row>
</Section>
<Section title="Grouped delay (adjacent tooltips open instantly)">
<Row>
<Tooltip content="Copy link">
<Button variant="ghost" color="neutral">
Copy
</Button>
</Tooltip>
<Tooltip content="Share">
<Button variant="ghost" color="neutral">
Share
</Button>
</Tooltip>
<Tooltip content="Delete">
<Button variant="ghost" color="error">
Delete
</Button>
</Tooltip>
</Row>
</Section>
</TooltipProvider>
);
}Vanilla — node tree to HTML
Tooltip — params.trigger: "hover"; the trigger wraps an arbitrary element (Base UI merges hover/focus onto it directly — a framework-free host instead gets a small inline wrapper, a documented simplification). Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.
npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviorsimport { atom, toHtml } from "@wizeworks/silicaui-html";
const node = atom("Tooltip", "tooltip", { /* props */ }, [/* children */]);
const markup = toHtml(node);Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "tooltip tooltip-primary" rather than passing a colour as a prop.
- Takes children
- yes
- Hydrated by
popover
Load @wizeworks/silicaui-behaviors on the page or this markup renders correctly and does nothing.
The full API for Tooltip, on every path, is available through the Silica MCP server.