
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A lightweight CSS animation trigger library that animates elements on click, hover, enter and more.
Triggle is a JavaScript library that makes it easy to control CSS animations using simple HTML attributes, no dependencies required. Triggle lets you add animations that respond to user actions like mouse clicks, hovers, key presses, scroll events, and more. Just use intuitive data-triggle attributes to trigger animations exactly when and how you want them.
Whether you're building interactive buttons, scroll effects, or playful UI animations, Triggle works beautifully and supports options like delays, durations, and auto-reset, giving you full control with minimal code.
click, mouseenter, scroll, keydown, etc.ctrl+s, shift+a, a*)data-triggle-nextdata-triggle-chain-delaydata-triggle-groupdata-triggle-staggerdata-triggle-once👉 Live Demo | Download via NPM | Check on jsDelivr | View on unpkg
npm install triggle
Then import it in your JavaScript:
// Default (unminified)
import "triggle";
// Optional: Use minified build explicitly
import "triggle/triggle.min.js";
<!-- Default build -->
<script src="https://cdn.jsdelivr.net/npm/triggle/dist/triggle.js"></script>
<!-- Minified build -->
<script src="https://cdn.jsdelivr.net/npm/triggle/dist/triggle.min.js"></script>
Both builds include all functionality. The minified version is optimized for production, while the unminified version is easier to debug.
Triggle is designed to work hand-in-hand with the animation classes from {css}animation. These CSS classes are required to make the triggers actually animate elements, so be sure to include them in your project.
Install the animation library:
npm install @hellouxpavel/cssanimation
Then import it in your JavaScript:
import "@hellouxpavel/cssanimation";
Or include it via CDN:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@hellouxpavel/cssanimation@latest/dist/cssanimation.min.css" />
Without the cssanimation classes, Triggle can still detect triggers, but no animation will play.
Trigger an animation on click.
To use Triggle, simply add data-triggle-* attributes to any HTML element you want to animate:
<div
class="cssanimation"
data-triggle="click"
data-triggle-class="ca__fx-elasticStretch"
data-triggle-reset="true">
Click to Animate
</div>
What each part does:
class="cssanimation" – Required. This enables animation support from the @hellouxpavel/cssanimation library.data-triggle – Specifies the event(s) that trigger the animation (e.g., click, mouseenter, keydown).data-triggle-class – The animation class (or classes) to apply when triggered.data-triggle-reset="true" – Optional. If set to "true", the animation class is removed after it finishes, allowing it to trigger again..cssanimation is required (from {css}animation).data-triggle-* attributes only on the intended element — avoid duplication on deeply nested structures to prevent conflicts.You can animate elements using the following trigger types via data-triggle:
| Trigger | Description |
|---|---|
click | On mouse click |
dblclick | On double click |
mouseenter | When the mouse enters the element |
mouseleave | When the mouse leaves the element |
mousedown | On mouse button press |
mouseup | On mouse button release |
focus | When an input or element gains focus |
blur | When focus is lost |
input | When input value changes |
keydown | On key press down |
keyup | On key release |
touchstart | On mobile touch start |
touchend | On mobile touch end |
animationend | After a CSS animation completes |
transitionend | After a CSS transition completes |
customEvent | Dispatched manually via JavaScript |
| Attribute | Type | Description |
|---|---|---|
data-triggle | string | Comma-separated events (e.g. click,mouseenter) |
data-triggle-class | string | Space-separated CSS classes to animate |
data-triggle-reset | true/false | Removes animation class after it finishes |
data-triggle-delay | string | CSS animation-delay (e.g., 0.5s) |
data-triggle-duration | string | CSS animation-duration (e.g., 1s) |
data-triggle-toggle | true/false | Toggles class on and off (instead of just adding) |
data-triggle-once | true/false | Triggers animation only once |
data-triggle-target | string | CSS selector(s) for external element(s) to animate instead of the trigger itself (e.g. .box1, #id) |
data-triggle-key | string | Keyboard filter (e.g. enter, ctrl+s, a*) |
data-triggle-next | string | CSS selector of element to animate after this one finishes |
data-triggle-chain-delay | number | Delay (in ms) before triggering data-triggle-next |
data-triggle-group | string | Group name to animate multiple elements together |
data-triggle-stagger | number | Delay (in ms) between each group's element animation |
data-triggle-scroll | true/false | Use IntersectionObserver to animate when element scrolls into view |
data-triggle-chain-loop | true | Enables infinite looping between chained elements |
This example shows how to trigger an animation on hover with custom timing and automatic reset:
<div
class="cssanimation"
data-triggle="mouseenter"
data-triggle-class="ca__fx-fadeIn"
data-triggle-delay="0.5s"
data-triggle-duration="2s"
data-triggle-reset="true">
Hover me to fade in
</div>
Timing Controls Use these attributes to control animation timing:
data-triggle-delay="0.2s" – Adds a delay before the animation starts.data-triggle-duration="1.5s" – Sets how long the animation should run.This example shows how to trigger an animation only for a single time:
<div
class="cssanimation"
data-triggle="click"
data-triggle-class="ca__fx-bounceIn"
data-triggle-once="true"
data-triggle-reset="true">
Click Me (Animates Once)
</div>
data-triggle-once="true" to ensure an animation only runs a single time, even if the triggering event happens again.Trigger animations using more than one event by separating them with commas in the data-triggle attribute
<div
class="cssanimation"
data-triggle="click, mouseenter"
data-triggle-class="ca__fx-rubber"
data-triggle-reset="true">
Click and Hover me for rubber animation
</div>
In the example above, the animation will trigger on both click and mouseenter.
data-triggle="click, mouseenter"" – List multiple event types separated by commas to trigger the animation from any of them.You can trigger animations on a different element using the data-triggle-target attribute:
<button data-triggle="click" data-triggle-target="#targetBox">
Animate Box
</button>
<div
id="targetBox"
class="cssanimation"
data-triggle-class="ca__fx-fadeIn"
data-triggle-reset="true"></div>
How it works
data-triggle-target="#box" – Selects the element to animate.data-triggle-class="ca__fx-fadeIn" – The class that will be applied to the target when the trigger fires.This is useful for triggering animations from buttons, controls, or any external source.
If you want to target multiple elements, separate them with commas in the data-triggle-target=".box, #banner, #triggleTarget" attribute:
<button
data-triggle="click"
data-triggle-target=".box, #banner, #triggleTarget">
Animate All
</button>
<div
class="cssanimation box"
data-triggle-class="ca__fx-fadeIn"
data-triggle-reset="true">
Target 1 by class
</div>
<div
id="banner"
class="cssanimation"
data-triggle-class="ca__fx-fadeIn"
data-triggle-reset="true">
Target 2 by ID
</div>
<div
id="triggleTarget"
class="cssanimation"
data-triggle-class="ca__fx-fadeIn"
data-triggle-reset="true">
Target 3 by ID
</div>
How it works
data-triggle-target=".box, #banner, #triggleTarget" – Selects multiple elements to animate.data-triggle-class="ca__fx-fadeIn" – The class that will be applied to the target when the trigger fires.Trigger animations on multiple elements at once using data-triggle-group.
<div
class="cssanimation"
data-triggle="click"
data-triggle-class="ca__fx-layerPeelIn"
data-triggle-group="cards"></div>
<div
class="cssanimation"
data-triggle-class="ca__fx-rollFromLeft"
data-triggle-reset="true"
data-triggle-group="cards"></div>
<div
class="cssanimation"
data-triggle-class="ca__fx-rollFromRight"
data-triggle-reset="true"
data-triggle-group="cards"></div>
How it works
data-triggle-group="cards" will animate together.Great for triggering multiple cards, icons, or UI components in sync from a single interaction.
Use data-triggle-toggle="true" to turn the animation class on and off with each trigger:
<div
data-triggle="click"
data-triggle-class="ca__fx-moonFade"
data-triggle-toggle="true">
Click to toggle bounce
</div>
How it works
ca__fx-moonFade class is added.This cycle continues on every interaction.
Useful for toggling active/inactive states with a single element.
Animate elements as they scroll into view using data-triggle-scroll="true":
<div
data-triggle="scroll"
data-triggle-scroll="true"
data-triggle-class="ca__fx-moonFadeUp"
data-triggle-reset="true"
data-triggle-once="true">
I animate when visible
</div>
How it works
ca__fx-moonFadeUp animation once when at least 50% of the element enters the viewport.data-triggle-once="true" ensures the animation happens only once per page load.data-triggle-reset="true" allows it to reset after animation completes (if once is not used).Perfect for scroll-based reveals and in-view transitions.
Use data-triggle-group and data-triggle-stagger to animate multiple elements in a coordinated sequence when a trigger element comes into view.
Trigger Element:
<div
data-triggle="scroll"
data-triggle-scroll="true"
data-triggle-group="TrgScroll"
data-triggle-class="ca__fx-moonFadeScaleUp"
data-triggle-stagger="300"
data-triggle-once="true"></div>
Staggered/Grouped Targets:
<div
data-triggle-class="ca__fx-moonFadeLeft"
data-triggle-reset="true"
data-triggle-group="TrgScroll">
Card A
</div>
<div
data-triggle-class="ca__fx-moonFadeRight"
data-triggle-reset="true"
data-triggle-group="TrgScroll">
Card B
</div>
<div
data-triggle-class="ca__fx-moonFade"
data-triggle-reset="true"
data-triggle-group="TrgScroll">
Card C
</div>
How it works
data-triggle-group.data-triggle-stagger="300" adds a 300ms delay between each target's animation.data-triggle-once="true" if you want the animation only fires once when the group scrolls into view.data-triggle-reset="true" if you want the animation to fire every time the group scrolls into view.Great for scroll reveals, feature sections, or card-based layouts with subtle animation cascades.
Chain multiple animations by using data-triggle-next and control timing with data-triggle-chain-delay.
<button
data-triggle="click"
data-triggle-class="ca__fx-swingIn"
data-triggle-reset="true"
data-triggle-next="#step2"
data-triggle-chain-delay="500">
Start
</button>
<div
id="step2"
data-triggle-class="ca__fx-systemBootIn"
data-triggle-reset="true" />
When the button is clicked:
ca__fx-swingInca__fx-swingIn finishes, triggle waits 500ms and then triggers #step2#step2 animates using the ca__fx-systemBootIn classKey Attributes
data-triggle-next="#selector" – Defines the next element to animate in sequence.data-triggle-chain-delay="500" – Wait time in milliseconds before triggering the next animation.Use chaining for guided flows, multi-step reveals, or onboarding sequences.
Create an infinite loop of chained animations between two or more elements.
<div
id="box1"
data-triggle="click"
data-triggle-class="ca__fx-squishPop"
data-triggle-next="#box2"
data-triggle-chain-delay="500"
data-triggle-chain-loop="true">
Start Loop
</div>
<div
id="box2"
data-triggle-class="ca__fx-layerPeelOut"
data-triggle-next="#box1"
data-triggle-chain-delay="500"></div>
How it works
#box1 starts the loop.#box1 animates with ca__fx-squishPop, then triggers #box2 after 500ms.#box2 animates with ca__fx-layerPeelOut, then triggers #box1 after 500ms.data-triggle-chain-loop="true" is set, the chain will repeat indefinitely.Useful for animated banners, instructional sequences, or continuous UI feedback loops.
Limit animations to specific key presses using data-triggle-key.
<div
data-triggle="keydown"
data-triggle-class="ca__fx-fadeIn"
data-triggle-key="ctrl+k,shift+a,a*"
data-triggle-reset="true">
Press keys
</div>
Supports:
data-triggle-key="Enter,Escape"data-triggle-key="en*, arrow*"data-triggle-key="ctrl+z, shift+a, alt+x"You can use any event name for data-triggle. This allows you to create custom event triggers using JavaScript's dispatchEvent() method. Example: data-triggle="notify" can be triggered by: element.dispatchEvent(new Event("notify"));
<div
id="notify"
data-triggle="customTriggleEvent"
data-triggle-class="ca__fx-flipX"
data-triggle-reset="true"></div>
<script>
document
.getElementById("notify")
.dispatchEvent(new Event("customTriggleEvent"));
</script>
If you prefer programmatic control, you can manually trigger animations using window.triggle.apply().
window.triggle.apply(
document.querySelector("#element"),
"ca__fx-jelly", // Animation class to apply
true, // Reset after animation ends
"0.3s", // Delay before animation starts
"1s", // Duration of the animation
false // Toggle mode (true = toggle, false = one-time)
);
Parameters
"0.3s")"1s")true to toggle the class on/offIdeal for triggering animations based on app logic, user input, or custom events.
If you're using Triggle in a single-page app (SPA) or need to reinitialize after DOM changes:
window.triggle.destroy(); // Removes all event listeners
window.triggle.init(); // Re-initializes all triggers
You can globally disable all Triggle animations, useful for accessibility, performance testing, or reduced motion preferences:
window.__trg_TRIGGER_DISABLED = true;
To re-enable:
window.__trg_TRIGGER_DISABLED = false;
window.triggle.init();
Enable debug mode to log internal behavior and aid in troubleshooting:
window.__trg_DEBUG = true;
To improve performance, Triggle uses passive event listeners for the following triggers:
touchstarttouchendscrollDOMContentLoaded for efficient event bindingdelay, duration)data-triggle-* attributes and goanimationend eventTriggle is proudly open-sourced under the Apache License 2.0. You can freely use it in personal, commercial, and creative projects.
Want a quick explanation? See the License Summary →
We welcome all contributions — whether it’s fixing bugs, adding feature, improving docs, or sharing ideas!
Help us make Triggle even more magical for everyone.
Running into issues while using Triggle in your project?
Whether it's a website, landing page, tool, or framework integration, we're here to help!
We’re happy to assist and make sure everything works smoothly in your setup.
If Triggle has saved you time, added a little magic to your UI, or helped bring your creative vision to life — please consider supporting its development.
This project is built with care, during late nights and weekends, with a passion for open-source and motion design. Your support helps me:
Every coffee counts — thank you for helping me keep creating. 🙏
If Triggle helped you ship faster, spark delight in your UI, or just made your day as a developer easier — I’d be honored to have your support.
This isn’t a big team or a funded project. It’s just me — Pavel — building tools I wish existed.
From late nights to early mornings, I pour love into every animation, every feature, every detail — to make the creative process more fun, expressive, and empowering for makers like you.
Your sponsorship helps me:
Let’s build a more playful, animated web — together.
FAQs
A lightweight CSS animation trigger library that animates elements on click, hover, enter and more.
The npm package triggle receives a total of 29 weekly downloads. As such, triggle popularity was classified as not popular.
We found that triggle demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.