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:
| Property | Value | Token |
|---|---|---|
| Background | #f3f4f6 | neutral-lightest |
| Text Color | #1e293b | slate-darkest |
| Border | #e5e7eb | neutral-lighter |
| Header Background | #001e50 | accent-deepBlue |
| Max Width | 280px | - |
| Border Radius | 0.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:
| Class | Purpose |
|---|---|
.tooltip-header | Dark blue header section |
.tooltip-specs | Container for specification rows |
.tooltip-row | Single specification row |
.tooltip-label | Left-aligned label text |
.tooltip-value | Right-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 tooltipflip()— flips placement when insufficient spaceshift({ padding: 5 })— shifts along axis to stay in viewportarrow()— positions the arrow element
Technical Details
Delegation Pattern
The tooltip system uses event delegation:
- Single event listener on
bodyhandles 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
- Global event listeners on
body(capture phase) watch formouseenter/mouseleave/focusin/focusout - When user hovers over a
[data-sds-tooltip]element, a single shared tooltip element is positioned using Floating UI’scomputePosition autoUpdatekeeps the tooltip position in sync during scroll/resize- 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
engine | Engine | Yes | Engine object with nested structure |
translations | EngineTranslations | No | Optional 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:
- ✅ Script imported in layout:
<script src="/src/scripts/tooltips.ts"></script> - ✅ Elements have
data-sds-tooltipattribute - ✅ Content is not empty or “undefined”
- ✅ Hard refresh browser (Ctrl+Shift+R) to clear cache
Double tooltips or conflicts
If you see duplicate tooltips:
- Only import the tooltip script once in your layout
- Don’t call
initTooltips()manually if using auto-initialization - Remove any local
tippy.jsinstallations that might conflict
Tooltips not working after navigation
If tooltips break after Astro View Transitions:
- Verify
astro:page-loadevent listener is registered (included in SDS script) - Check browser console for errors
- Make sure View Transitions are properly configured in Astro
Styling not applied
- Verify SDS tooltip CSS is imported (included in SDS tooltip script)
- Check CSS specificity
- 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:
- Remove
tippy.jsfrom yourpackage.json - Update SDS to latest version
- Replace
data-tippy-contentwithdata-sds-tooltipon all elements - Update custom styles from
.tippy-box[data-theme~='sds']to.sds-tooltip - Remove any tippy.js imports or initialization code
Related Documentation
- ProductEngine Component - Engine codes with tooltips
- ProductCodes Component - PR codes with tooltips
- Floating UI Documentation - Positioning engine