@zkreations/tooltips
v5.1.3
Published
Tiny and powerful tooltips with pure CSS
Maintainers
Readme
Why this instead of a JS-based tooltip library
Most tooltip libraries require JavaScript to calculate positions, attach event listeners, and manage visibility state. This library does none of that — all behavior is declared in CSS.
Features
- Pure CSS. No JavaScript, dependencies, or configuration.
- Native positioning. Uses CSS Anchor Positioning to calculate position and automatically flip sides when space is limited.
- Minimal code. The stylesheet contains only the rules needed for base behavior; it does not include classes for positions, styles, or animations you may not use.
- CSS-driven configuration. Each tooltip can define its position, appearance, and animation through CSS custom properties, according to the project's needs.
- No layout shift. Positioning occurs during the browser's layout calculation, without measuring the DOM after render.
- Accessible. Uses
aria-labelas content and shows tooltips on:focus. - Automatic fallback. Browsers without CSS Anchor Positioning use an absolute top-centered position.
[!IMPORTANT] CSS Anchor Positioning is a relatively recent browser feature. Browsers that do not support it receive a predictable fallback (centered, absolute top bubble) rather than dynamic placement.
Installation
npm
npm i @zkreations/tooltipsFrameworks and bundlers
The package exports its minified CSS as the default style entry:
import '@zkreations/tooltips';Import it once in the application entrypoint:
Next.js
// app/layout.tsx or pages/_app.tsx
import '@zkreations/tooltips';Astro
---
import '@zkreations/tooltips';
---The same import works with Vite, Nuxt, SvelteKit, and other bundlers that support CSS package imports. If a bundler does not resolve the package style entry, import the file explicitly:
import '@zkreations/tooltips/index.min.css';Do not import both paths — they contain the same stylesheet.
Sass
Use the Sass entry only when the project needs to compile the source itself:
@use '@zkreations/tooltips/scss/tooltip';Do not also import the package CSS in that case. Most projects should use the compiled CSS entry instead.
CDN
<link href="https://cdn.jsdelivr.net/npm/@zkreations/tooltips@5/index.min.css" rel="stylesheet"/>Usage
Add the .tooltip class and the aria-label attribute to any HTML element:
<button type="button" class="tooltip" aria-label="Hello world!">
Hover or focus me
</button>Positioning
Tooltips appear at the top (block-start) by default and flip automatically (flip-block, flip-inline) when space is limited:
.tooltip::before {
position-area: var(--tt-area, block-start);
position-try-fallbacks: var(--tt-fallbacks, flip-block, flip-inline);
}To set a custom position, override --tt-area:
.tooltip--right { --tt-area: inline-end; }
.tooltip--left { --tt-area: inline-start; }
.tooltip--bottom { --tt-area: block-end; }To force a position without automatic flipping:
.tooltip--fixed-right {
--tt-area: inline-end;
--tt-fallbacks: none;
}Programmatic visibility
To show a tooltip without hover or focus, add data-tooltip-visible:
<button type="button" class="tooltip" aria-label="Active notification" data-tooltip-visible>
Notifications
</button>Customization
Override CSS variables to adjust the appearance:
| Variable | Default | Description |
| --- | --- | --- |
| --tt-area | block-start | Position area relative to anchor |
| --tt-fallbacks | flip-block, flip-inline | Fallback positions if clipped |
| --tt-gap | 0.5rem | Spacing between anchor and tooltip |
| --tt-bg | rgb(0 0 0 / 90%) | Background color |
| --tt-color | #fff | Text color |
| --tt-size | 0.875rem | Font size |
| --tt-padding | 0.5em 0.75em | Bubble padding |
| --tt-radius | 0.25em | Border radius |
| --tt-shadow | none | Box shadow |
| --tt-max-width | 20rem | Maximum bubble width |
| --tt-z-index | 10 | Stacking order |
| --tt-duration | 0.2s | Transition duration |
| --tt-ease | ease | Transition timing function |
| --tt-start | none | Transform on hidden state (e.g. scale(0.85), translateY(6px)) |
| --tt-end | none | Transform on visible state |
Example:
.tooltip--custom {
--tt-bg: #2563eb;
--tt-color: #ffffff;
--tt-radius: 8px;
--tt-padding: 8px 12px;
--tt-shadow: 0 4px 12px rgb(0 0 0 / 15%);
--tt-gap: 0.5rem;
}Compact version
If you prefer not to use CSS variables and want the smallest possible footprint, the project provides a compact variant (compact.css / compact.min.css) that retains automatic positioning via CSS Anchor Positioning alongside the fallback for unsupported browsers.
Given how small it is (~1 KB unminified / ~800 B minified), we recommend copying the contents of compact.css directly into your project's stylesheet instead of adding it as an external dependency. This gives you direct and complete control over the tooltip styles in CSS without going through variables.
If you still prefer importing it from the package:
import '@zkreations/tooltips/compact.min.css';No arrow by design
v5 does not include a pseudo-element arrow (::after). flip-block and flip-inline change bubble placement without communicating orientation changes to pseudo-element borders consistently across browsers, which produces visual bugs. Omitting the arrow avoids those bugs and keeps the stylesheet smaller.
Browser compatibility
- Browsers supporting CSS Anchor Positioning use
@supports (position-area: block-start)for dynamic placement and automatic flipping. - Browsers without support receive a static fallback: a centered, absolute top bubble.
- Current support: Can I Use — CSS Anchor Positioning.
Migration from v4 to v5
| v4 | v5 |
| --- | --- |
| [data-tts] | .tooltip |
| data-tts-visible | data-tooltip-visible |
| [data-tts="down"] | --tt-area: block-end; |
| [data-tts="left"] | --tt-area: inline-start; |
| [data-tts="right"] | --tt-area: inline-end; |
| --tts-* | --tt-* |
| tooltips.min.css | index.min.css |
Support
If you want to help keep this project updated, you can buy me a coffee.
License
MIT License
