Tooltip
A tooltip is a short label for another element, shown on hover and on focus: it names an icon button, or says what a control does, in a few words. It holds nothing to act on. See the M3 tooltips guidelines.
Usage
The tooltip describes its target: 300ms after the pointer enters it or it takes focus, the
tooltip shows, below it by default. The web component's target is the element its for
attribute names.
import { createTooltip, createIconButton } from 'mtrl';
const trigger = createIconButton({ icon: heartOutlineIcon, ariaLabel: 'Favorite' });
document.body.append(trigger.element);
const tooltip = createTooltip({ target: trigger.element, text: 'Add to favorites' });
document.body.append(tooltip.element);
<m-icon-button id="tooltip-target" aria-label="Favorite"></m-icon-button>
<m-tooltip text="Add to favorites" for="tooltip-target"></m-tooltip>
<script type="module">
document.querySelector('#tooltip-target').setAttribute('icon', heartOutlineIcon);
</script>
import { Tooltip, IconButton } from 'mtrl/react';
import { heartOutlineIcon } from './app';
export function Example() {
return (
<>
<IconButton id="tooltip-target" icon={heartOutlineIcon} ariaLabel="Favorite" />
<Tooltip text="Add to favorites" for="tooltip-target" />
</>
);
}
<script setup lang="ts">
import { MTooltip, MIconButton } from 'mtrl/vue';
import { heartOutlineIcon } from './app';
</script>
<template>
<MIconButton id="tooltip-target" :icon="heartOutlineIcon" aria-label="Favorite" />
<MTooltip text="Add to favorites" for="tooltip-target" />
</template>
<script lang="ts">
import { Tooltip, IconButton } from 'mtrl/svelte';
import { heartOutlineIcon } from './app';
</script>
<IconButton id="tooltip-target" icon={heartOutlineIcon} ariaLabel="Favorite" />
<Tooltip text="Add to favorites" for="tooltip-target" />
import { Tooltip, IconButton } from 'mtrl/solid';
import { heartOutlineIcon } from './app';
export function Example() {
return (
<>
<IconButton id="tooltip-target" icon={heartOutlineIcon} ariaLabel="Favorite" />
<Tooltip text="Add to favorites" for="tooltip-target" />
</>
);
}
Examples
Position
position is top, right, bottom or left, each also with -start or -end to align it
with an edge of the target. It is kept inside the window's width.
import { createTooltip, createIconButton } from 'mtrl';
const trigger = createIconButton({ icon: shareIcon, ariaLabel: 'Share' });
document.body.append(trigger.element);
const tooltip = createTooltip({ target: trigger.element, text: 'Share', position: 'top' });
document.body.append(tooltip.element);
<m-icon-button id="tooltip-target" aria-label="Share"></m-icon-button>
<m-tooltip text="Share" position="top" for="tooltip-target"></m-tooltip>
<script type="module">
document.querySelector('#tooltip-target').setAttribute('icon', shareIcon);
</script>
import { Tooltip, IconButton } from 'mtrl/react';
import { shareIcon } from './app';
export function Example() {
return (
<>
<IconButton id="tooltip-target" icon={shareIcon} ariaLabel="Share" />
<Tooltip text="Share" position="top" for="tooltip-target" />
</>
);
}
<script setup lang="ts">
import { MTooltip, MIconButton } from 'mtrl/vue';
import { shareIcon } from './app';
</script>
<template>
<MIconButton id="tooltip-target" :icon="shareIcon" aria-label="Share" />
<MTooltip text="Share" position="top" for="tooltip-target" />
</template>
<script lang="ts">
import { Tooltip, IconButton } from 'mtrl/svelte';
import { shareIcon } from './app';
</script>
<IconButton id="tooltip-target" icon={shareIcon} ariaLabel="Share" />
<Tooltip text="Share" position="top" for="tooltip-target" />
import { Tooltip, IconButton } from 'mtrl/solid';
import { shareIcon } from './app';
export function Example() {
return (
<>
<IconButton id="tooltip-target" icon={shareIcon} ariaLabel="Share" />
<Tooltip text="Share" position="top" for="tooltip-target" />
</>
);
}
Timing and triggers
showDelay and hideDelay are in milliseconds. showOnHover: false leaves it to focus, and
showOnFocus: false to the pointer; show() and hide() drive it from script.
import { createTooltip, createIconButton } from 'mtrl';
const trigger = createIconButton({ icon: settingsIcon, ariaLabel: 'Settings' });
document.body.append(trigger.element);
const tooltip = createTooltip({
target: trigger.element,
text: 'Settings',
showDelay: 600,
hideDelay: 0,
showOnHover: false,
});
document.body.append(tooltip.element);
<m-icon-button id="tooltip-target" aria-label="Settings"></m-icon-button>
<m-tooltip text="Settings" show-delay="600" hide-delay="0" no-show-on-hover for="tooltip-target"></m-tooltip>
<script type="module">
document.querySelector('#tooltip-target').setAttribute('icon', settingsIcon);
</script>
import { Tooltip, IconButton } from 'mtrl/react';
import { settingsIcon } from './app';
export function Example() {
return (
<>
<IconButton id="tooltip-target" icon={settingsIcon} ariaLabel="Settings" />
<Tooltip text="Settings" showDelay={600} hideDelay={0} noShowOnHover for="tooltip-target" />
</>
);
}
<script setup lang="ts">
import { MTooltip, MIconButton } from 'mtrl/vue';
import { settingsIcon } from './app';
</script>
<template>
<MIconButton id="tooltip-target" :icon="settingsIcon" aria-label="Settings" />
<MTooltip text="Settings" :show-delay="600" :hide-delay="0" no-show-on-hover for="tooltip-target" />
</template>
<script lang="ts">
import { Tooltip, IconButton } from 'mtrl/svelte';
import { settingsIcon } from './app';
</script>
<IconButton id="tooltip-target" icon={settingsIcon} ariaLabel="Settings" />
<Tooltip text="Settings" showDelay={600} hideDelay={0} noShowOnHover for="tooltip-target" />
import { Tooltip, IconButton } from 'mtrl/solid';
import { settingsIcon } from './app';
export function Example() {
return (
<>
<IconButton id="tooltip-target" icon={settingsIcon} ariaLabel="Settings" />
<Tooltip text="Settings" showDelay={600} hideDelay={0} noShowOnHover for="tooltip-target" />
</>
);
}
setTarget() moves a tooltip to another element, so one tooltip can serve a list. layer: 'top' shows it in the browser's top layer, above any clipping or stacking; the web component
always is.
API
Options
| Option | Type | Default | Description |
|---|---|---|---|
text |
string |
undefined |
The label |
target |
HTMLElement |
undefined |
The element it describes |
position |
TooltipPosition |
'bottom' |
Where it sits against the target |
variant |
'default' | 'plain' | 'rich' |
'default' |
default and plain are M3's plain tooltip, on inverse-surface; rich is M3's rich tooltip, on surface-container |
visible |
boolean |
false |
Whether it shows at once |
showDelay / hideDelay |
number |
300 / 100 |
How long before it shows or hides, in ms |
showOnHover / showOnFocus |
boolean |
true |
Whether the pointer, and focus, show it |
layer |
'top' |
undefined |
Shows it in the top layer, after its target in the target's tree |
zIndex |
number |
undefined |
Its z-index, outside the top layer |
rich |
boolean |
false |
Deprecated, never applied: use variant: 'rich'; the text is always text |
class |
string |
undefined |
Additional CSS classes |
prefix |
string |
'mtrl' |
Prefix for CSS class names |
The web component takes for, text (or its own text), position, variant, show-delay,
hide-delay, no-show-on-hover and no-show-on-focus, and a target property that wins over
for.
Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
show(immediate?) / hide(immediate?) |
immediate?: boolean |
TooltipComponent |
Shows or hides it, at once when immediate |
isVisible() |
none | boolean |
Whether it is shown |
getText() / setText(text) |
text: string |
string / TooltipComponent |
The label |
getPosition() / setPosition(position) |
position: TooltipPosition |
string / TooltipComponent |
Where it sits |
setTarget(target) |
target: HTMLElement |
TooltipComponent |
Describes another element |
updatePosition() |
none | TooltipComponent |
Places it again against its target |
destroy() |
none | void |
Releases its target and removes it |
| Property | Type | Description |
|---|---|---|
element |
HTMLElement |
The tooltip |
target |
HTMLElement | null |
The element it describes |
A tooltip has no events.
Accessibility
- A
tooltip, and its target'saria-describedbynames it: the label is read as the target's description. It does not name the target; an icon button still needs its ownariaLabel. - Focus shows it as the pointer does, and
Escapehides it without moving focus. - The pointer can move from the target onto the tooltip without it hiding.
- Hidden, it is
aria-hidden.
Styling
.mtrl-tooltip, .mtrl-tooltip--visible { }
.mtrl-tooltip--default, .mtrl-tooltip--plain, .mtrl-tooltip--rich { }
.mtrl-tooltip--top, .mtrl-tooltip--right, .mtrl-tooltip--bottom, .mtrl-tooltip--left { }
.mtrl-tooltip__arrow { }
Measurements
| Attribute | Value |
|---|---|
| Container | inverse-surface, opaque, no elevation, 4dp corners, 200dp wide at most |
| Text | Body Small, inverse-on-surface |
| Padding | 4dp above and below, 8dp at the sides |
| Rich | surface-container, 12dp corners, elevation 2, 320dp wide at most; Body Medium, on-surface-variant; 12dp above and below, 16dp at the sides |
| Distance from the target | 8dp |