Tooltips

Classic tooltips by default, optional Material colors, and the legacy Tooltip API.

Tippy.js integration based on an animated-fill configuration. These examples use Tippy 6.3.7 and the kmaterialize tooltip adapter.

Use focusable buttons or links as triggers. Text is treated as plain text by default. The legacy Materialize Tooltip API remains available; initialize only one tooltip library per trigger.

Choose a style

Two previews share the same behavior: animated fill, no arrow, and automatic placement. Classic uses Tippy’s original dark colors. Material uses this website’s inverse surface tokens and follows the theme. Classic is the default for new tooltips and Crazy button. Choose Material explicitly when you want theme-colored tooltips.

<button id="tippy-classic" class="btn filled" type="button">Classic</button>
<button id="tippy-material" class="btn tonal" type="button">Material colors</button>
import { createTooltip } from 'kmaterialize/tippy';

// Classic is the default; Material is an explicit alternative.
createTooltip(document.querySelector<HTMLElement>('#tippy-classic')!, {
  content: 'Save your review notes',
});
createTooltip(document.querySelector<HTMLElement>('#tippy-material')!, 'material', {
  content: 'Save your review notes',
});

Placement

Automatic placement finds available space. Override placement when you prefer a side; Tippy can reposition to fit the viewport.

<button type="button" class="btn outlined" data-tooltip-placement="top">Top</button>
<button type="button" class="btn outlined" data-tooltip-placement="right">Right</button>
<button type="button" class="btn outlined" data-tooltip-placement="bottom">
  Bottom
</button>
<button type="button" class="btn outlined" data-tooltip-placement="left">Left</button>
for (const target of document.querySelectorAll<HTMLElement>(
  '[data-tooltip-placement]',
)) {
  createTooltip(target, 'classic', {
    content: `Preferred placement: ${target.dataset.tooltipPlacement}`,
    placement: target.dataset.tooltipPlacement as 'top' | 'right' | 'bottom' | 'left',
  });
}

Click or tap

Hover and keyboard focus work with the default trigger. A click trigger is useful when you want a tap-controlled hint. Escape or an outside click dismisses this example.

<button id="tippy-touch" class="btn tonal" type="button">Tap for help</button>
createTooltip(document.querySelector<HTMLElement>('#tippy-touch')!, 'classic', {
  content: 'Tap outside or press Escape to dismiss.',
  trigger: 'click',
});

Template content

The basic example passes a plain label string to Tippy. For richer content, clone your own HTML template. Keep tooltip content informational; use a popover with focus management for interactive actions.

<button id="tippy-template" class="btn filled" type="button">Review details</button>
<template id="tippy-content-template">
  <div class="tippy-demo-content">
    <strong>Ready for review</strong>
    <span>The latest movie and notes are attached.</span>
  </div>
</template>
const template = document.querySelector<HTMLTemplateElement>(
  '#tippy-content-template',
)!;
createTooltip(document.querySelector<HTMLElement>('#tippy-template')!, 'classic', {
  content: template.content.firstElementChild!.cloneNode(true) as HTMLElement,
});

Setup and methods

// Install: pnpm add tippy.js@6.3.7
// Install the optional tippy.js peer and load its CSS plus Materialize CSS.
import { createTooltip } from 'kmaterialize/tippy';

const button = document.querySelector<HTMLElement>('#my-button')!;
const tooltip = createTooltip(button, { content: 'Initial description' });
tooltip.setContent('Updated description');
// tooltip.show();
// tooltip.hide();
// tooltip.setProps({ placement: 'bottom' });
// tooltip.destroy(); // Call when removing the view.

The adapter returns a standard Tippy instance. Reduced-motion preferences disable the fill animation. Escape dismisses tooltips without moving focus. Destroy instances when removing their triggers.

Load the optional peer’s styles once, before Materialize CSS:

import 'tippy.js/dist/tippy.css';
import 'tippy.js/dist/backdrop.css';
import 'tippy.js/animations/shift-away.css';
import 'kmaterialize/dist/css/materialize.css';
Optional Material theme SCSS
// Optional Material palette; the classic variant uses unmodified Tippy colors.
.tippy-box[data-theme~='materialize'] {
  background-color: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  > .tippy-backdrop {
    background-color: var(--md-sys-color-inverse-surface);
  }
  > .tippy-arrow {
    color: var(--md-sys-color-inverse-surface);
  }
}

Crazy button

Floating, icon, and FAB buttons with a label use Classic automatically. The optional tippy.js peer loads when needed. Use tooltip-style="material" for Material colors and tooltip-position for placement. Await button.updateComplete then button.tooltipReady when you need to inspect a tooltip instance after an update. Rerendering or removing a button destroys its tooltip.

<crazy-button icon-text="home" label="Home" tooltip-position="right"></crazy-button>
<crazy-button icon-text="palette" label="Material colors" tooltip-style="material"></crazy-button>

Legacy Materialize Tooltip API

Existing Tooltip.init and .tooltipped integrations retain their original behavior and require no Tippy peer. Use this section when maintaining those integrations; Classic above is the default for new examples and Crazy button. Initialize only one tooltip implementation per trigger.

<button class="btn tonal tooltipped" type="button" data-position="right" data-tooltip="Original Materialize tooltip">Legacy tooltip</button>
import { Tooltip } from 'kmaterialize';
const instance = Tooltip.init(element, {
  text: 'Description',
  position: 'right',
});
// Or M.AutoInit() for .tooltipped elements.
instance.open();
instance.close();
Tooltip.getInstance(element);
instance.destroy();

For authored content, set data-tooltip-id to an existing element’s ID, or pass tooltipId. Keep tooltip content informational; use a popover for interactive controls.

Legacy optionDefaultPurpose
text / tooltipIdEmpty / unsetPlain text or the ID of an existing content element.
positionbottomtop, right, bottom, or left.
enterDelay / exitDelay0 / 200msDelay before showing / hiding.
inDuration / outDuration300 / 250msShow / hide transition durations.
margin / transitionMovement5 / 10pxTrigger spacing / transition distance.
opacity1Visible opacity.

Instance properties: el, options, isOpen, and isHovered.