Tooltips

A complete tooltip system built on Floating UI with custom SDS styling and automatic initialization.

Features

  • 🎨 Custom SDS Theme - Matches design system colors
  • Performance Optimized - Delegation pattern handles thousands of tooltips efficiently
  • 🔄 Astro View Transitions - Automatic re-initialization on navigation
  • 🎯 Simple API - Just add a data attribute
  • 📦 Bundled - No need to install Floating UI separately in your project
  • 🔍 SEO Friendly - Content rendered in HTML, enhanced progressively
  • 🪶 Lightweight - ~3 KB gzip (Floating UI) vs ~14 KB (tippy.js + popper)

Installation

Step 1: Create a tooltip initialization script

In your project, create a script file (e.g., src/scripts/tooltips.ts):

// src/scripts/tooltips.ts
import 'spoko-design-system/scripts/tooltips';

That’s it! This single import includes:

  • ✅ Floating UI positioning engine
  • ✅ SDS tooltip CSS
  • ✅ Auto-initialization logic
  • ✅ Astro View Transitions support

Step 2: Import in your layout

Add the script to your main layout’s <head>:

---
// src/layouts/BaseLayout.astro or HeadCommon.astro
---

<head>
  <!-- ... other head elements -->
  <script src="/src/scripts/tooltips.ts"></script>
</head>

Usage

Basic Tooltip

Add the data-sds-tooltip attribute to any element:

<button data-sds-tooltip="This is a basic tooltip">
  Hover over me
</button>

HTML Content

Tooltips support HTML content:

HTML tooltip

<span data-sds-tooltip="<strong>Bold text</strong> and <em>italic text</em>">
  HTML tooltip
</span>

Structured Tooltips

For complex tooltips with headers and multiple sections:

Product Info

<span data-sds-tooltip={`
  <div class="tooltip-header">
    <strong>Product Details</strong>
  </div>
  <div class="tooltip-specs">
    <div class="tooltip-row">
      <span class="tooltip-label">SKU:</span>
      <span class="tooltip-value">12345</span>
    </div>
    <div class="tooltip-row">
      <span class="tooltip-label">Weight:</span>
      <span class="tooltip-value">2.5 kg</span>
    </div>
  </div>
`}>
  Product Info
</span>

Custom Placement

Override the default top placement per element:

<span data-sds-tooltip="Appears below" data-sds-tooltip-placement="bottom">
  Bottom tooltip
</span>

Supported placements: top, bottom, left, right, top-start, top-end, bottom-start, bottom-end, left-start, left-end, right-start, right-end.

Components with Built-in Tooltips

These SDS components automatically include tooltips:

ProductEngine & ProductEngines

Engine codes with detailed specification tooltips:

import { ProductEngines } from 'spoko-design-system';

<ProductEngines engines={product.part_engines} />

See ProductEngine documentation for details.

ProductCodes

PR codes with description tooltips (when available):

import { ProductCodes } from 'spoko-design-system';

<ProductCodes prcodes={product.pr_codes} isPdp={true} />

Styling

SDS Theme

The default SDS theme uses these design tokens:

PropertyValueToken
Background#f3f4f6neutral-lightest
Text Color#1e293bslate-darkest
Border#e5e7ebneutral-lighter
Header Background#001e50accent-deepBlue
Max Width280px-
Border Radius0.5rem-

Custom Styling

To customize the tooltip appearance, override these CSS classes:

/* Main tooltip box */
.sds-tooltip {
  background-color: your-color;
  color: your-text-color;
}

/* Tooltip content area */
.sds-tooltip-content {
  padding: 0.5rem 0.75rem;
}

/* Structured tooltip header */
.sds-tooltip .tooltip-header {
  background-color: your-header-color;
  color: white;
  padding: 0.375rem 0.5rem;
}

/* Tooltip specs rows */
.sds-tooltip .tooltip-row {
  display: flex;
  justify-content: space-between;
  padding: 0.25rem 0;
}

Available CSS Classes

For structured tooltips:

ClassPurpose
.tooltip-headerDark blue header section
.tooltip-specsContainer for specification rows
.tooltip-rowSingle specification row
.tooltip-labelLeft-aligned label text
.tooltip-valueRight-aligned value text

Configuration

The tooltip system uses these default settings:

{
  selector: '[data-sds-tooltip]',  // Target selector
  placement: 'top',                // Default placement
  offset: 8,                       // Gap between trigger and tooltip (px)
  maxWidth: 280,                   // Maximum width (px)
  showDelay: 80,                   // Delay before showing (ms)
  hideDelay: 60,                   // Delay before hiding (ms)
}

Floating UI middleware used:

  • offset(8) — gap between trigger and tooltip
  • flip() — flips placement when insufficient space
  • shift({ padding: 5 }) — shifts along axis to stay in viewport
  • arrow() — positions the arrow element

Technical Details

Delegation Pattern

The tooltip system uses event delegation:

  • Single event listener on body handles all tooltips
  • No re-initialization needed when DOM changes
  • Efficient memory usage - one shared tooltip element reused for all triggers
  • Dynamic content support - works with client-side rendering

How It Works

  1. Global event listeners on body (capture phase) watch for mouseenter/mouseleave/focusin/focusout
  2. When user hovers over a [data-sds-tooltip] element, a single shared tooltip element is positioned using Floating UI’s computePosition
  3. autoUpdate keeps the tooltip position in sync during scroll/resize
  4. On mouse leave, tooltip fades out and cleanup runs

Astro View Transitions

The system automatically handles Astro’s View Transitions:

document.addEventListener('astro:page-load', () => {
  initTooltips();
});

document.addEventListener('astro:before-swap', () => {
  // Cleanup tooltip element before page swap
});

This ensures tooltips work correctly after client-side navigation.

API Reference

initTooltips()

Initializes the global tooltip delegation. Safe to call multiple times — only attaches listeners once.

Import:

import { initTooltips } from 'spoko-design-system';

Usage:

initTooltips();

Note: Usually not needed if you import 'spoko-design-system/scripts/tooltips' which auto-initializes.

showTooltip(target)

Programmatically show tooltip on a target element.

import { showTooltip } from 'spoko-design-system/scripts/tooltips';

showTooltip(document.querySelector('[data-sds-tooltip]'));

hideTooltip()

Programmatically hide the current tooltip.

import { hideTooltip } from 'spoko-design-system/scripts/tooltips';

hideTooltip();

getEngineTooltipContent()

Generates HTML content for engine tooltips.

Import:

import { getEngineTooltipContent } from 'spoko-design-system';

Usage:

const tooltipHTML = getEngineTooltipContent(engine, translations);

Parameters:

ParameterTypeRequiredDescription
engineEngineYesEngine object with nested structure
translationsEngineTranslationsNoOptional translation overrides

Returns: HTML string for tooltip content

See ProductEngine documentation for Engine interface details.

Dependencies

SDS includes @floating-ui/dom as a dependency. Your project does not need to install it separately.

If you have tippy.js in your project’s package.json, you can safely remove it:

pnpm remove tippy.js

Troubleshooting

Tooltips not showing

Check these items:

  1. ✅ Script imported in layout: <script src="/src/scripts/tooltips.ts"></script>
  2. ✅ Elements have data-sds-tooltip attribute
  3. ✅ Content is not empty or “undefined”
  4. ✅ Hard refresh browser (Ctrl+Shift+R) to clear cache

Double tooltips or conflicts

If you see duplicate tooltips:

  1. Only import the tooltip script once in your layout
  2. Don’t call initTooltips() manually if using auto-initialization
  3. Remove any local tippy.js installations that might conflict

Tooltips not working after navigation

If tooltips break after Astro View Transitions:

  1. Verify astro:page-load event listener is registered (included in SDS script)
  2. Check browser console for errors
  3. Make sure View Transitions are properly configured in Astro

Styling not applied

  1. Verify SDS tooltip CSS is imported (included in SDS tooltip script)
  2. Check CSS specificity
  3. Ensure your build process handles CSS imports from node_modules

Browser Support

Tooltips work in all modern browsers:

  • ✅ Chrome/Edge (latest)
  • ✅ Firefox (latest)
  • ✅ Safari (latest)
  • ✅ Mobile browsers (iOS Safari, Chrome Android)

Note: Requires JavaScript. Content is still visible if JS is disabled (progressive enhancement).

Examples

Product Specification

<dl>
  <dt>Weight</dt>
  <dd>
    <span data-sds-tooltip="Includes packaging">
      2.5 kg
    </span>
  </dd>
</dl>

Help Icons

<label>
  Email
  <span
    class="inline-block ml-1 text-gray-400 cursor-help"
    data-sds-tooltip="We'll never share your email">

  </span>
</label>

Technical Terms

<p>
  The part fits all
  <abbr
    data-sds-tooltip="Volkswagen Aktiengesellschaft Group"
    class="cursor-help underline decoration-dotted">
    VAG
  </abbr>
  vehicles from 2009-2014.
</p>

Best Practices

Do

  • Use semantic HTML with tooltips as enhancement
  • Keep tooltip content concise (< 50 words)
  • Use structured tooltips for multiple data points
  • Include proper ARIA labels when needed
  • Test on mobile devices

Don’t

  • Put critical information only in tooltips
  • Use tooltips for large blocks of text
  • Nest interactive elements inside hover tooltips (use click trigger instead)
  • Initialize tooltips multiple times

Migration from tippy.js

If migrating from a tippy.js implementation:

  1. Remove tippy.js from your package.json
  2. Update SDS to latest version
  3. Replace data-tippy-content with data-sds-tooltip on all elements
  4. Update custom styles from .tippy-box[data-theme~='sds'] to .sds-tooltip
  5. Remove any tippy.js imports or initialization code