
## Tooltips

`ui-tooltip` is the rich tooltip primitive. It uses the native [interest invoker API](https://open-ui.org/components/interest-invokers.explainer/) (`interestfor` + `popover="hint"`) combined with [CSS Anchor Positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning) — no JavaScript needed in modern Chrome/Edge. For older browsers, load [Platform.js](/platformjs) as a polyfill. Supports HTML content, interactive children, hover-into behavior, auto-flipping when there's no room, and color/size variants.

For plain text, label-only tooltips, use [Simple Tooltips](/simple-tooltips) instead.

### Anatomy

A tooltip has two parts: a **trigger** with `interestfor="some-id"`, and a **tooltip element** with `popover="hint"` and a matching `id`. The tooltip's `position-anchor: auto` automatically anchors it to the trigger.

```html
<button type="button" interestfor="tip-save">Save</button>
<div id="tip-save" class="ui-tooltip" popover="hint">Saves the document</div>
```

<br>

&gt; ⚠️ **`interestfor` is guaranteed to work on `<button>` and `<a href>` elements in modern browsers.** For other elements, see [Troubleshooting](#troubleshooting).

<br>

### Basic Tooltip


  
    <button type="button" class="ui-button --sm" interestfor="tip-basic">Hover me</button>
    <div id="tip-basic" class="ui-tooltip" popover="hint">I'm a tooltip</div>
  


```html
<button type="button" class="ui-button --sm" interestfor="tip-basic">Hover me</button>
<div id="tip-basic" class="ui-tooltip" popover="hint">I'm a tooltip</div>
```

### Position

Use `--top` (default), `--bottom`, `--left`, or `--right`. The tooltip auto-flips if there isn't room in the chosen direction.


  
    <button type="button" class="ui-button --sm" interestfor="tip-pos-top">Top</button>
    <div id="tip-pos-top" class="ui-tooltip" popover="hint">Top (default)</div>

    <button type="button" class="ui-button --sm" interestfor="tip-pos-bottom">Bottom</button>
    <div id="tip-pos-bottom" class="ui-tooltip --bottom" popover="hint">Bottom</div>

    <button type="button" class="ui-button --sm" interestfor="tip-pos-left">Left</button>
    <div id="tip-pos-left" class="ui-tooltip --left" popover="hint">Left</div>

    <button type="button" class="ui-button --sm" interestfor="tip-pos-right">Right</button>
    <div id="tip-pos-right" class="ui-tooltip --right" popover="hint">Right</div>
  


```html
<div id="tip-bottom" class="ui-tooltip --bottom" popover="hint">Bottom</div>
<div id="tip-left" class="ui-tooltip --left" popover="hint">Left</div>
<div id="tip-right" class="ui-tooltip --right" popover="hint">Right</div>
```

### Size (multi-line content)

Add `--small` (80px), `--medium` (150px), or `--large` (300px) for body copy that needs to wrap.


  
    <button type="button" class="ui-button --sm" interestfor="tip-size-sm">Small</button>
    <div id="tip-size-sm" class="ui-tooltip --small" popover="hint">A brief tooltip that wraps.</div>

    <button type="button" class="ui-button --sm" interestfor="tip-size-md">Medium</button>
    <div id="tip-size-md" class="ui-tooltip --medium" popover="hint">A slightly longer tooltip for when you need a sentence or two of context.</div>

    <button type="button" class="ui-button --sm" interestfor="tip-size-lg">Large</button>
    <div id="tip-size-lg" class="ui-tooltip --large" popover="hint">A large tooltip — room enough for a full paragraph of guidance, a keyboard shortcut reference, or a quick explanation of a tricky concept.</div>
  


```html
<div class="ui-tooltip --small" popover="hint">…</div>
<div class="ui-tooltip --medium" popover="hint">…</div>
<div class="ui-tooltip --large" popover="hint">…</div>
```

### Color Variants

Use `--error`, `--warning`, `--info`, or `--success` to signal semantic meaning.


  
    <button type="button" class="ui-button --sm" interestfor="tip-color-err">Error</button>
    <div id="tip-color-err" class="ui-tooltip --error" popover="hint">Something went wrong</div>

    <button type="button" class="ui-button --sm" interestfor="tip-color-warn">Warning</button>
    <div id="tip-color-warn" class="ui-tooltip --warning" popover="hint">Heads up — irreversible</div>

    <button type="button" class="ui-button --sm" interestfor="tip-color-info">Info</button>
    <div id="tip-color-info" class="ui-tooltip --info" popover="hint">Just so you know…</div>

    <button type="button" class="ui-button --sm" interestfor="tip-color-ok">Success</button>
    <div id="tip-color-ok" class="ui-tooltip --success" popover="hint">All saved</div>
  


### Rich Content

Unlike simple tooltips, `ui-tooltip` accepts any HTML: headings, keyboard shortcuts, images, icons.


  
    <button type="button" class="ui-button --sm" interestfor="tip-rich">Hover for details</button>
    <div id="tip-rich" class="ui-tooltip --medium" popover="hint">
      <strong style="display:block; margin-bottom: 2px;">Keyboard shortcut</strong>
      <span style="opacity: 0.7;">Press <kbd style="background:rgba(255,255,255,0.15); padding: 1px 4px; border-radius: 3px; font-size: 0.75rem;">Ctrl+S</kbd> to save</span>
    </div>
  


```html
<button type="button" class="ui-button --sm" interestfor="tip-rich">Hover for details</button>
<div id="tip-rich" class="ui-tooltip --medium" popover="hint">
  <strong>Keyboard shortcut</strong>
  <span>Press <kbd>Ctrl+S</kbd> to save</span>
</div>
```

### Hoverable (interactive) Tooltip

By default the tooltip hides as soon as the cursor leaves the trigger. Add `--hoverable` to the trigger to add a small delay so users can mouse into the tooltip and click things inside.


  
    <button type="button" class="ui-button --sm --hoverable" interestfor="tip-interactive">Interactive</button>
    <div id="tip-interactive" class="ui-tooltip --large" popover="hint" style="padding: 12px;">
      <strong style="display:block; margin-bottom: 4px;">Need help?</strong>
      <span style="opacity: 0.7; display:block; margin-bottom: 8px;">You can hover into this tooltip and click the button below.</span>
      <a href="/" class="ui-button --solid --sm">Open docs</a>
    </div>
  


```html
<button type="button" class="ui-button --sm --hoverable" interestfor="tip-interactive">Interactive</button>
<div id="tip-interactive" class="ui-tooltip --large" popover="hint">
  <strong>Need help?</strong>
  <span>You can hover into this tooltip and click the button below.</span>
<a href="/" class="ui-button --solid --sm">Open docs</a>
</div>
```

### Custom Delays

Show/hide delays are driven by the `interest-delay` CSS property (or the `--ui-tooltip-delay-show` / `--ui-tooltip-delay-hide` / `--ui-tooltip-delay-hoverable-hide` variables).

```css
:root {
  --ui-tooltip-delay-show: 0.3s;
  --ui-tooltip-delay-hide: 0.1s;
}
```

### Customization

All visual and timing values are driven by CSS variables on `:root`. Override any of them to restyle globally:

| Variable | Default |
|----------|---------|
| `--ui-tooltip-background-color` | `var(--ui-color-gray-900)` |
| `--ui-tooltip-text-color` | `#fff` |
| `--ui-tooltip-font-size` | `0.85rem` |
| `--ui-tooltip-line-height` | `1rem` |
| `--ui-tooltip-padding` | `8px` |
| `--ui-tooltip-border-radius` | `var(--ui-shared-element-border-radius)` |
| `--ui-tooltip-box-shadow` | `0 0 0.5rem rgba(0, 0, 0, 0.1)` |
| `--ui-tooltip-offset` | `6px` |
| `--ui-tooltip-delay-show` | `0s` |
| `--ui-tooltip-delay-hide` | `0s` |
| `--ui-tooltip-delay-hoverable-hide` | `0.5s` |
| `--ui-tooltip-transition-duration` | `0.15s` |
| `--ui-tooltip-width-small` | `80px` |
| `--ui-tooltip-width-medium` | `150px` |
| `--ui-tooltip-width-large` | `300px` |
| `--ui-tooltip-color-error` | `#dc2626` |
| `--ui-tooltip-color-warning` | `#d97706` |
| `--ui-tooltip-color-info` | `#2563eb` |
| `--ui-tooltip-color-success` | `#16a34a` |

### Troubleshooting

If your tooltip doesn't work:

1. Check that the trigger has `interestfor="your-id"` and the tooltip has `popover="hint"` with a matching `id`.
2. Check whether the trigger element is a `<button>` or `<a href="...">`. Native support targets those reliably.
3. If your trigger is a different element (`<span>`, `<div>`, etc.):
   - Wrap it in `<button type="button">...</button>`, or
   - Include `platform.js` so older browsers get a polyfill for `interestfor`.

If you still see issues, ensure the popup has space to show (it needs room to render near the trigger) and that no parent element blocks overflow.
</div></span></a></button></a></button>