Tooltip
A Tailwind CSS tooltip component for displaying informational text on hover or when the element receives keyboard focus.
<button class="btn" aria-describedby="tip-1">Hover me</button>
<div id="tip-1" class="tooltip" role="tooltip">Tooltip text</div>To attach a tooltip to a trigger, point the trigger's aria-describedby at the tooltip's id.
Placement
Use data-sp-placement on the tooltip to control its position relative to the trigger (default is top).
<button class="btn" aria-describedby="tip-left">Left</button>
<div id="tip-left" class="tooltip" role="tooltip" data-sp-placement="left">Left tooltip</div>
<button class="btn" aria-describedby="tip-top">Top</button>
<div id="tip-top" class="tooltip" role="tooltip" data-sp-placement="top">Top tooltip</div>
<button class="btn" aria-describedby="tip-bottom">Bottom</button>
<div id="tip-bottom" class="tooltip" role="tooltip" data-sp-placement="bottom">Bottom tooltip</div>
<button class="btn" aria-describedby="tip-right">Right</button>
<div id="tip-right" class="tooltip" role="tooltip" data-sp-placement="right">Right tooltip</div>Animation
The tooltip includes a default fade and zoom animation. Add no-animation to disable it, or use your own classes with data-[state=open]: selectors.
<button class="btn" aria-describedby="tip-default">Default</button>
<div id="tip-default" class="tooltip" role="tooltip">Default animation</div>
<button class="btn" aria-describedby="tip-noanim">No Animation</button>
<div id="tip-noanim" class="tooltip no-animation" role="tooltip">No animation</div>
<button class="btn" aria-describedby="tip-slide">Slide from Bottom</button>
<div
id="tip-slide"
class="tooltip no-animation data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-bottom"
role="tooltip"
>
Custom animation
</div>The default animations use tw-animate-css utilities. You can customize or replace these with your own animations.
How it works
The tooltip component uses a small JavaScript module that handles showing, hiding, and positioning the tooltip content.
Structure
A tooltip consists of two elements linked by aria-describedby:
- Any focusable element (button, link, etc.) with
aria-describedby="tooltip-id" .tooltipwith a matchingidandrole="tooltip"— the floating content panel
<button aria-describedby="my-tip">Hover me</button>
<div id="my-tip" class="tooltip" role="tooltip">Tooltip text</div>The trigger and the tooltip can live anywhere in the DOM as long as the id matches.
Opening and closing
The tooltip opens automatically when the user hovers over or focuses the trigger. It closes when the mouse leaves or the trigger loses focus. Pressing Escape also closes the tooltip.
Tooltips do not move focus into themselves and do not intercept clicks — clicking the trigger does whatever the trigger normally does (submit a form, navigate, etc.).
Animation
The tooltip includes a default fade and zoom animation. When shown, the JavaScript sets data-state="open" on the tooltip element.
To customize animations, add no-animation to disable the defaults and use your own classes with data-[state=open]: selectors:
<div
id="my-tip"
class="tooltip no-animation data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom"
role="tooltip"
>
<!-- Custom slide animation -->
</div>Accessibility
The tooltip JavaScript module shows content on both hover and keyboard focus, and pressing Escape closes it.
Add role="tooltip" to the tooltip element so screen readers announce it correctly:
<div id="my-tip" class="tooltip" role="tooltip">Tooltip text</div>aria-describedby on the trigger is required — that's how the tooltip is discovered. Without it the JavaScript has no way to know which tooltip belongs to which trigger.
<button class="btn" aria-describedby="save-tip">Save</button>
<div id="save-tip" class="tooltip" role="tooltip">
Saves your changes
</div>Keyboard navigation
| Key | Action |
|---|---|
Tab | Focus trigger to show tooltip |
Escape | Closes the tooltip |
Class reference
All available classes for the tooltip component.
| Class | Description |
|---|---|
tooltip | The floating content that appears on hover/focus |
tooltip-arrow | Arrow element (auto-injected by JavaScript) |
no-animation | Disables default animation on the tooltip |
<button aria-describedby="my-tip">Hover me</button>
<div id="my-tip" class="tooltip" role="tooltip">Tooltip text</div>Data attributes
All data attributes for the tooltip component.
| Attribute | Element | Description |
|---|---|---|
aria-describedby | Trigger | Required — id of the linked .tooltip |
data-sp-placement | .tooltip | Tooltip position (default: top) |
data-state | .tooltip | Set to open when tooltip is visible |
<button class="btn" aria-describedby="my-tip">Hover me</button>
<div id="my-tip" class="tooltip" role="tooltip" data-sp-placement="bottom">
Tooltip text
</div>