
easy-tooltips is a lightweight tooltip library that attaches customizable, hover- and tap-triggered tooltips to any elements.
Features
- Adds tooltips through HTML data attributes.
- Works with mouse hover, touch input, and keyboard focus.
- Repositions tooltips to stay inside the viewport.
- Flips tooltips above, below, left, or right when space runs out.
- Anchors tooltips to the element, cursor, touch point, or first activation point.
- Uses skip-delay timing for fast movement between adjacent tooltips.
- Supports CSS variable customization.
- Draws the tooltip body and arrow with a single SVG path.
- Applies custom classes to specific tooltips.
- Supports custom HTML content from a template or nearby element.
- Updates automatically when frontend frameworks change the DOM.
Use Cases
- Add short help text to buttons, links, labels, and form controls.
- Show validation hints on focusable fields without a full UI framework.
- Add multi-line product, dashboard, or settings explanations inside compact interfaces.
- Use custom tooltip panels for formatted details from templates or adjacent markup.
How to use it:
1. Install and import easy-tooltips into your project.
# NPM $ npm install easy-tooltips
import "easy-tooltips/styles.css" import "easy-tooltips"
2. Or use it directly in the browser:
<link rel="stylesheet" href="dist/easy-tooltips.min.css" /> <script src="dist/easy-tooltips.min.js"></script>
3. Add the data-easy-tooltip attribute to your target elements:
<span data-easy-tooltip="Tooltip Content"> Hover Me </span> <span data-easy-tooltip="Multi-line<br>Tooltip"> Hove Me </span>
4. To prevent XSS vulnerabilities. You can no longer insert raw HTML strings via data-tooltip since v4. Instead, use data-tooltip-src and provide a selector to source content from.
<button data-tooltip-src="#target">Hover Me</button> <template id="target"> Tooltip Content Here </template>
<button data-tooltip-src="next">Or fetch content from the next element</button> <div> Tooltip Content Here </div>
5. Add data-easy-tooltip-class when one tooltip needs a different visual treatment. The value becomes a class on the generated tooltip.
<button data-easy-tooltip="Saved" data-easy-tooltip-class="success-tooltip"> Save </button> <button data-easy-tooltip="This deletes the selected record" data-easy-tooltip-class="danger-tooltip bold-tooltip"> Delete </button>
.success-tooltip {
--easy-tooltip-background-color: #f0fdf4;
--easy-tooltip-border-color: #27ae60;
--easy-tooltip-text-color: #166534;
}
.danger-tooltip {
--easy-tooltip-background-color: #fef2f2;
--easy-tooltip-border-color: #e74c3c;
--easy-tooltip-text-color: #991b1b;
}
.bold-tooltip {
font-weight: 700;
}6. Use data-easy-tooltip-prefer to choose the first side that easy-tooltips should try. The tooltip still flips to the opposite side when the preferred side does not have enough room.
<button data-easy-tooltip="Appears below when space allows" data-easy-tooltip-prefer="below"> Below </button> <button data-easy-tooltip="Appears on the right when space allows" data-easy-tooltip-prefer="right"> Right </button>
7. Use data-easy-tooltip-anchor when the tooltip should attach to a point instead of the trigger element. The default element mode follows the element box, cursor follows the pointer or touch point, and pin locks the tooltip to the first hover or tap position while the page scrolls.
<button data-easy-tooltip="Tracks the pointer" data-easy-tooltip-anchor="cursor"> Inspect point </button> <button data-easy-tooltip="Stays at the first activation point" data-easy-tooltip-anchor="pin"> Pin tooltip </button>
8. You can also override the default CSS variables to make global changes.
:root {
--easy-tooltip-background-color: #fff;
--easy-tooltip-text-color: #000;
--easy-tooltip-border-color: #aaa;
--easy-tooltip-border-size: 1px;
--easy-tooltip-border-radius: 4px;
--easy-tooltip-padding: 8px 12px;
--easy-tooltip-max-width: 100%;
--easy-tooltip-animation-distance: 4px;
--easy-tooltip-distance: 16px;
--easy-tooltip-viewport-padding: 16px;
--easy-tooltip-arrow-size: 12px;
--easy-tooltip-arrow-edge-buffer-x: 12px;
--easy-tooltip-arrow-edge-buffer-y: 6px;
--easy-tooltip-arrow-radius: 0;
--easy-tooltip-animation-length: 0.15s;
--easy-tooltip-delay: 0.15s;
}Changelog:
v3.0.3 (06/18/2026)
- Bugfixes
v3.0.2 (06/08/2026)
- Bugfixes
v3.0.1 (05/25/2026)
- Bugfixes
v3.0.0 (05/24/2026)
- Anchor modes: new data-easy-tooltip-anchor attribute with element (default), cursor (tooltip follows the cursor or touch point), and pin (tooltip pins at the first hover/tap location and stays there as the page scrolls).
- Smart skip-delay: the first hover waits briefly to ignore accidental movement, but subsequent adjacent tooltips appear instantly. Controlled by two new variables: –easy-tooltip-inactive-delay (extra delay applied while no tooltip was recently active) and –easy-tooltip-cooldown (time after the last tooltip closes before the inactive-delay applies again).
- Two-value arrow size: –easy-tooltip-arrow-size: <width> <height> specifies width and depth independently. Single value still works (height defaults to width / 2).
- Newest-on-top stacking: when multiple tooltips are visible at once, the most recently activated one renders above earlier ones.
- Body and arrow are now drawn as a single continuous SVG path instead of a styled inner element with a CSS-positioned arrow. Eliminates the subpixel seam between them and enables stroke/fill techniques (dashed borders, gradient fills, drop shadows) by targeting .easy-tooltip-bg (the SVG element) and .easy-tooltip-bg path (the outline + fill). Any CSS targeting .easy-tooltip::before or the old mask-based arrow no longer applies.
- .easy-tooltip-text no longer carries CSS background or border; these are drawn by the SVG path. Style via the –easy-tooltip-background-color / -border-color / -border-size variables, or target .easy-tooltip-bg path for advanced styling. CSS background-image, box-shadow, etc. on the body element no longer apply.
- –easy-tooltip-arrow-size semantics changed: no more √2 scaling. A single value X means width = X, height = X/2. Two-value form X Y specifies explicit width × height.
- –easy-tooltip-arrow-size default changed from 12px (which produced a ~17×8.5 visible arrow under the old scaling) to 16px (16×8 visible).
- –easy-tooltip-delay default changed from 0.15s to 0s. The first-hover wait moved to the new –easy-tooltip-inactive-delay variable (default 0.15s).
- –easy-tooltip-arrow-radius now rounds the arrow tip with an SVG arc rather than a corner of the rotated square. Same default (0); visual differs at larger values.
v2.0.0 (05/22/2026)
- Added more data attributes.
- Renamed several data attributes.
- Bugfixed.
v1.5.0 (03/16/2026)
- Added dynamic tooltip support with MutationObserver
v1.4.4 (03/05/2026)
- Update readme
v1.4.3 (01/26/2026)
- Added newline support. Newline characters will be rendered properly within tooltips.
- Fixed custom html tooltip formatting
- Added tooltip delays, customisable via –tooltip-delay. Defaults to .15s
- Fixed XSS vulnerabilities. You can no longer insert raw HTML strings via data-tooltip. Instead, use data-tooltip-src and provide a selector to source content from.
v1.2.9 (12/21/2025)
- Fixed global scope pollution
v1.2.8 (12/21/2025)
- Fix not loading if added after dom content has already fully loaded
v1.2.7 (09/17/2025)
- Fix tooltips getting stuck on mobile
- Fix crash when loaded before DOM is ready
- Fix global scope pollution
v1.2.4 (08/05/2025)
- Fix tooltips persisting on screen when the tooltip element is deleted while you hover it
- Mobile performance improvements
v1.2.3 (07/27/2025)
- Actually fixes max-width being broken for the page width
- Now compatible with VueJS, React, etc
v1.1.0 (07/10/2025)
- Fix tooltip alignment issue and allow variables to be animated






