@h-k-dev/angular-tooltips

July 3, 2026 · View on GitHub

npm version CI/CD license: MIT

Warning

Experimental — Chrome only for now. This library is built on bleeding-edge platform features (CSS Anchor Positioning, position-visibility, anchored container queries, and Interest Invokers) that are currently only fully supported in Chrome and other Chromium-based browsers. Everywhere else the directive degrades to the native title attribute. Expect breaking changes while the underlying specs and this API settle.

Modern, lightweight tooltips for Angular. One singleton popover element, positioned entirely by CSS Anchor Positioning — no overlay module, no scroll listeners, no per-trigger DOM.

Live demo →

Why another tooltip library?

  • Singleton architecture — a single tooltip element is re-pointed between anchors instead of being destroyed and recreated. Sweep across a dense grid and the tooltip glides; the enter animation never restarts mid-sweep (the classic MatTooltip flicker).
  • Top layer, always — the tooltip is a native [popover], so it renders above dialogs and is never clipped by overflow or z-index stacking contexts.
  • CSS does the work — placement, auto-flipping at the viewport edge, tail direction, and hide-when-scrolled-out (position-visibility: anchors-visible) are all handled by the browser.
  • Browser-native triggering for links — on <a href> elements in supporting browsers, the Interest Invokers (interestfor) path is used: the browser owns hover, keyboard focus, touch long-press, and delays.
  • Works on any element<button>, <a>, <span>, <div>, <img>, <input>, icons, component hosts…
  • Graceful degradation — browsers without CSS Anchor Positioning fall back to the native title attribute.

Installation

npm install @h-k-dev/angular-tooltips

Usage

Import the standalone directive and attach it to anything:

import { Component } from '@angular/core';
import { HkTooltip } from '@h-k-dev/angular-tooltips';

@Component({
  selector: 'app-demo',
  imports: [HkTooltip],
  template: `
    <button [hkTooltip]="'Save your progress'">Save</button>

    <button hkTooltip="Deletes immediately" hkTooltipPlacement="right" [hkTooltipDelay]="300">
      Delete
    </button>

    <a href="/docs" hkTooltip="Opens the documentation">Docs</a>
  `,
})
export class Demo {}

API

[hkTooltip] directive

InputTypeDefaultDescription
hkTooltipstring (required)Tooltip text.
hkTooltipPlacement'top' | 'bottom' | 'left' | 'right''top'Preferred side; auto-flips when space runs out.
hkTooltipDelaynumber (ms)0Delay before showing.
hkTooltipHideDelaynumber (ms)80Delay before hiding.

[hkTooltipRoot] directive

Optional. Scopes the event delegation to a subtree (for example a virtualized grid) instead of document.body.

Theming

The tooltip is styled through CSS custom properties with the --tt- prefix. Every variable falls back to the Angular Material tooltip tokens, then the --mat-sys-* system tokens, then a built-in default:

--tt-*  (your theme)  →  --mat-tooltip-*  →  --mat-sys-*  →  default

With an Angular Material theme present, the tooltip matches it out of the box. Without Material, the defaults give you the familiar dark M3 look. Override on :root (or any ancestor of <body>):

:root {
  --tt-container-color: #1e293b;
  --tt-text-color: #e2e8f0;
  --tt-border-radius: 8px;
  --tt-max-width: 320px;
}
VariablePurposeMaterial fallbackDefault
--tt-container-colorBackground of bubble and tail--mat-tooltip-container-color--mat-sys-inverse-surface#313033
--tt-text-colorText color--mat-tooltip-supporting-text-color--mat-sys-inverse-on-surface#f4eff4
--tt-border-radiusCorner radius--mat-tooltip-container-shape--mat-sys-corner-extra-small4px
--tt-font-familyFont family--mat-tooltip-supporting-text-font--mat-sys-body-small-fontRoboto, sans-serif
--tt-font-sizeFont size--mat-tooltip-supporting-text-size--mat-sys-body-small-size12px
--tt-font-weightFont weight--mat-tooltip-supporting-text-weight--mat-sys-body-small-weight400
--tt-line-heightLine height--mat-tooltip-supporting-text-line-height--mat-sys-body-small-line-height1.4
--tt-letter-spacingLetter spacing--mat-tooltip-supporting-text-tracking--mat-sys-body-small-tracking0.033em
--tt-shadowBox shadownone
--tt-paddingInner padding6px 10px
--tt-max-widthMaximum width280px
--tt-gapDistance from the anchor8px
--tt-tail-sizeTail (arrow) size6px
--tt-enter-durationSlide-in duration0.3s
--tt-fade-durationFade-in duration0.15s
--tt-slide-distanceSlide-in distance10px

Keep --tt-tail-size smaller than --tt-gap, so the tail never overlaps the trigger.

Browser support

CapabilityBehaviour
CSS Anchor PositioningFull experience: singleton popover, auto-flip, scroll tracking.
Interest Invokers (interestfor)Additionally: browser-native triggering on <a href> links.
NeitherFalls back to the native title attribute.

Development

npm start                        # demo app on http://localhost:4200
npm run test:ci                  # headless vitest suite
npm run build angular-tooltips   # build the library into dist/

Releases are automated with semantic-release: conventional commits pushed to main (or beta for prereleases) publish to npm and GitHub Packages and deploy the demo to GitHub Pages.

License

MIT