/Documentation

Tooltip

PublishedUpdated

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.

Vanilla
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);
Web Components
<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>
React
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" />
    </>
  );
}
Vue
<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>
Svelte
<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" />
SolidJS
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.

Vanilla
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);
Web Components
<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>
React
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" />
    </>
  );
}
Vue
<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>
Svelte
<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" />
SolidJS
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.

Vanilla
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);
Web Components
<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>
React
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" />
    </>
  );
}
Vue
<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>
Svelte
<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" />
SolidJS
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's aria-describedby names it: the label is read as the target's description. It does not name the target; an icon button still needs its own ariaLabel.
  • Focus shows it as the pointer does, and Escape hides 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