A child .tooltip is the bubble. No
tooltipped class is required. They are CSS only on
hover and keyboard focus. Helpers are only for placement and
the rich variant: top (the default),
bottom, left, right,
rich / max.
Tokens follow the
M3 tooltip spec.
A plain tooltip is inverse-surface /
inverse-on-surface, 4dp corners,
body-small, 24dp minimum, 4/8dp padding, 200dp
max, no elevation and no caret. It sits 4dp from the activator.
M3 prefers above.
Inside a <button> the bubble has to be a
<span> — a <div> is not
phrasing content and the parser will hoist it. Icon-only
buttons still need .circle so the span is not
treated as a label.
<button type="button" class="circle" aria-label="Add" aria-describedby="tip-add-to-album">
<span class="material-symbols" aria-hidden="true">add</span>
<span class="tooltip" id="tip-add-to-album">Add to album</span>
</button>
<button type="button" class="circle" aria-label="Below" aria-describedby="tip-below">
<span class="material-symbols" aria-hidden="true">arrow_downward</span>
<span class="tooltip bottom" id="tip-below">Below</span>
</button>
Rich
rich (or BeerCSS’s max) is the rich
tooltip: surface, elevation 2, 12dp corners,
320dp max. A heading is the title
(title-small), a <p> is
supporting text (body-medium), and a trailing
<nav> is the action. Rich bubbles can
receive pointer events so the action is usable.
Saved offline
This stop is stored on the device so it still opens without a signal.
<div>
<button type="button" class="tonal">Why this is saved</button>
<div class="tooltip rich bottom">
<h3>Saved offline</h3>
<p>This stop is stored on the device so it still opens without a signal.</p>
<nav>
<button type="button" class="text">Got it</button>
</nav>
</div>
</div>
A rich tooltip with an action cannot live inside a
<button> — that would nest buttons. Put the
bubble next to the control, wrapped in a parent.
JavaScript
The CSS path does not need AutoInit. The JS plugin is still
there for data-tooltip, delayed show/hide, and
keeping the bubble inside the viewport. Add
tooltipped to the activator.
data-tooltip is the text;
data-position is top,
right, bottom, or
left. AutoInit() starts every
.tooltipped except those marked
no-autoinit. The generated element gets both
.tooltip and .material-tooltip.
<a class="tooltipped" data-position="bottom" data-tooltip="I am a tooltip" href="#!">
Hover me
</a>
For HTML, point data-tooltip-id at an element.
That element is moved into the tooltip and the bubble is
marked rich. Leave data-tooltip off
so the HTML is kept. There is no data-html
attribute and no unsafeHTML option.
<a class="tooltipped" href="#!"
data-position="bottom" data-tooltip-id="tooltip-content">
With HTML
</a>
<div id="tooltip-content" hidden>
<h3>Chart</h3>
<p>This is a tooltip with a <a href="https://github.com">link</a>.</p>
</div>
Initialization
The IIFE bundle exposes Expressive.Tooltip.
Call init yourself when you need options other
than the defaults, or let
Expressive.AutoInit() start every
.tooltipped.
document.addEventListener('DOMContentLoaded', function() {
const elems = document.querySelectorAll('.tooltipped');
const instances = Expressive.Tooltip.init(elems, {
enterDelay: 200
});
});
Per-instance options can also be passed through AutoInit:
Expressive.AutoInit(document.body, {
Tooltip: { enterDelay: 200 }
});
Options
Constructor and init options.
data-tooltip, data-position, and
data-tooltip-id are read from the element and
override these defaults. Attributes are read again each time
the tooltip opens, so changing them later takes effect on the
next show.
| Name | Type | Default | Description |
|---|---|---|---|
exitDelay |
Number | 200 |
Delay before the tooltip disappears, in milliseconds. |
enterDelay |
Number | 0 |
Delay before the tooltip appears, in milliseconds. |
tooltipId |
String | — | Id of an element used as the tooltip body. Set by data-tooltip-id. Marks the bubble rich. |
text |
String | '' |
Plain-text content. Set by data-tooltip. Ignored when tooltipId is set. |
margin |
Number | 4 |
Distance from the activator, in pixels, not counting transitionMovement. M3 is 4dp. |
inDuration |
Number | 250 |
Enter transition duration, in milliseconds. |
opacity |
Number | 1 |
Opacity of the tooltip when shown. |
outDuration |
Number | 200 |
Exit transition duration, in milliseconds. |
position |
String | 'bottom' |
Direction: 'top', 'right', 'bottom', or 'left'. Set by data-position. The CSS-only default is above. |
transitionMovement |
Number | 10 |
How far the tooltip moves during its transition, in pixels. |
Methods
All methods are called on the plugin instance. You can get the instance like this:
const instance = Expressive.Tooltip.getInstance(elem);
.open();
Show the tooltip.
instance.open();
.close();
Hide the tooltip.
instance.close();
.destroy();
Destroy the plugin instance, remove the tooltip element, and tear down its event handlers.
instance.destroy();
Properties
| Name | Type | Description |
|---|---|---|
el |
Element | The DOM element the plugin was initialized with. |
options |
Object | The options the instance was initialized with. |
isOpen |
Boolean | Whether the tooltip is open. |
isHovered |
Boolean | Whether the activator is hovered. |
isFocused |
Boolean | Whether the activator is focused via the keyboard. |
tooltipEl |
Element | The generated tooltip element. |