Put the control in the trigger slot and the description in the default slot. Hover opens after 600 ms, focus opens immediately, and Escape closes without moving focus. The text becomes the trigger’s accessible description; it never replaces the control’s name, so an icon button still needs its own aria-label. Pointer movement from the trigger into the content keeps it open. Touch does not create a persistent tooltip. Its description is associated with the actual focusable native control, including a Button’s shadow root.
Sides
side takes physical or logical values (block-start by default) and align positions the tooltip along that side. Collisions with the viewport can flip the resolved side. The positioner uses the browser top layer without moving authored content out of its theme or slot context. Flip, shift, available-size constraints, arrow placement and anchor visibility are recomputed on scroll, resize, content changes and layout movement. Hidden or disconnected anchors cannot leave a visible stale popup.
Sides
Default density
Compact density
Restart from the initial state
Show the copyable source
AboveShown aboveAfterShown after the triggerBelowShown belowBeforeShown before the trigger
AboveShown aboveAfterShown after the triggerBelowShown belowBeforeShown before the trigger
<tp-tooltip side="block-start"><tp-button slot="trigger" variant="outline">Above</tp-button>Shown above</tp-tooltip>
<tp-tooltip side="inline-end"><tp-button slot="trigger" variant="outline">After</tp-button>Shown after the trigger</tp-tooltip>
<tp-tooltip side="block-end"><tp-button slot="trigger" variant="outline">Below</tp-button>Shown below</tp-tooltip>
<tp-tooltip side="inline-start"><tp-button slot="trigger" variant="outline">Before</tp-button>Shown before the trigger</tp-tooltip>
Keyboard hints
Descriptions can include an Icon or Kbd. Links, buttons and inputs cannot go inside; use Popover for interactive content.
With a shortcut
Default density
Compact density
Restart from the initial state
Show the copyable source
open-delay and close-delay tune pointer timing in milliseconds. Keep the open delay for dense toolbars so tooltips don’t flash as the pointer passes; shorten it where the description is the point.
Delays
Default density
Compact density
Restart from the initial state
Show the copyable source
InstantOpens with no delayPatientWaits 1.2 seconds to open
InstantOpens with no delayPatientWaits 1.2 seconds to open
<tp-tooltip open-delay="0"><tp-button slot="trigger" variant="outline">Instant</tp-button>Opens with no delay</tp-tooltip>
<tp-tooltip open-delay="1200" close-delay="300"><tp-button slot="trigger" variant="outline">Patient</tp-button>Waits 1.2 seconds to open</tp-tooltip>
Following the pointer
track-cursor-axis positions the tooltip at the pointer along one or both axes, which suits wide targets such as a chart or a progress track.
Cursor tracking
Default density
Compact density
Restart from the initial state
Show the copyable source
Storage: 42 GB of 100 GB used
Photos 28 GB · Documents 9 GB · Other 5 GB
Storage: 42 GB of 100 GB used
Photos 28 GB · Documents 9 GB · Other 5 GB
<tp-tooltip track-cursor-axis="horizontal" side="block-start">
<div slot="trigger" tabindex="0" style="display:grid;place-items:center;inline-size:28rem;max-inline-size:100%;min-block-size:5rem;border:1px dashed var(--tp-border);border-radius:var(--tp-radius-lg);color:var(--tp-muted-foreground);font-size:var(--tp-text-sm)">
Storage: 42 GB of 100 GB used
</div>
Photos 28 GB · Documents 9 GB · Other 5 GB
</tp-tooltip>
Toolbar groups
In a toolbar, the first tooltip should wait but the next ones should not. Give the tooltips one TooltipProvider from @tweakpad/ui: after one opens, moving to a neighbour opens its tooltip at once, until the pointer has rested away for restTimeout (400 ms by default). Only one tooltip in the group is open at a time.
Shared provider
Default density
Compact density
Restart from the initial state
Show the copyable source
A long list does not need a tooltip per row. Create a handle with createTooltipHandle(), attach one Tooltip to it, and register each trigger with a payload. The Tooltip’s content renders the payload of whichever trigger is active, here with html from lit.
Shared handle
Default density
Compact density
Restart from the initial state
Show the copyable source
registerTrigger() returns a cleanup function, and handle.open(identifier) opens the tooltip for one trigger from code.
Disabled
Disabled tooltip
Default density
Compact density
Restart from the initial state
Show the copyable source
Archive
Move this project to the archive
Archive
Move this project to the archive
<tp-tooltip disabled>
<tp-button slot="trigger" variant="outline">Archive</tp-button>
Move this project to the archive
</tp-tooltip>
disabled on the Tooltip suppresses the description only; the Button it describes stays active and keeps its hover appearance.
API Reference
Every element also accepts motion-policy.
Properties
PropertyTypeDefaultDescriptiondescribesTooltipDescribes'trigger'trigger makes the text the trigger's accessible description; none keeps the tooltip visual
only, for a trigger whose name already says the same, such as a Play button whose tooltip shows
"Play" and its shortcut.
Events
EventTypeDescriptiontp-open-changeTpSurfaceOpenChangeEventCancelable proposal to open or close, before the surface changes; detail.value is the proposed state, detail.reason what asked (a trigger press, hover or focus, Escape, an outside press, a close action or code) and detail.trigger the trigger. On a close, detail.preventUnmountOnClose() keeps the content mounted.tp-open-change-completeCustomEvent<{ open: boolean; }>After the surface finishes opening or closing; detail.open.
Slots
SlotDescriptiondefaultThe description: text, with an Icon or a Kbd.triggerThe focusable control the tooltip describes.
CSS parts
PartDescription::part(tooltip)The host around the trigger and the tooltip.
Related
Components, widgets and patterns that use this one.