triggle
Version:
A lightweight CSS animation trigger library that animates elements on click, hover, enter and more.
658 lines (482 loc) β’ 25.5 kB
Markdown
# Animate with Triggle β Simple Trigger-Based CSS Animation Control



[](https://www.npmjs.com/package/triggle)
[](https://www.npmjs.com/package/triggle)



[](https://www.jsdelivr.com/package/npm/triggle)
[](https://unpkg.com/browse/triggle/)
[](https://yesiamrocks.github.io/Triggle/)
[](https://github.com/yesiamrocks/cssanimation)
[](https://www.buymeacoffee.com/yesiamrocks) [](https://www.buymeacoffee.com/yesiamrocks/membership)
**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.
## Features
- Animate on `click`, `mouseenter`, `scroll`, `keydown`, etc.
- Animate any element or target another with a selector
- Reset animation classes automatically
- Toggle class on/off with a single trigger
- Trigger with keyboard key filters (`ctrl+s`, `shift+a`, `a*`)
- Chain animations using `data-triggle-next`
- Delay the next animation with `data-triggle-chain-delay`
- Trigger multiple elements at once with `data-triggle-group`
- Stagger animations across groups with `data-triggle-stagger`
- One-time animation triggers with `data-triggle-once`
- Cleanup & reinitialization support
- Developer debug logging
π [Live Demo](https://yesiamrocks.github.io/triggle/) | [Download via NPM](https://www.npmjs.com/package/triggle) | [Check on jsDelivr](https://www.jsdelivr.com/package/npm/triggle) | [View on unpkg](https://app.unpkg.com/triggle@1.2.0)
## Installation
### Using NPM
```bash
npm install triggle
```
Then import it in your JavaScript:
```js
// Default (unminified)
import "triggle";
// Optional: Use minified build explicitly
import "triggle/triggle.min.js";
```
### Using CDN
```html
<!-- 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.
## Animation Classes Powered by {css}animation
**Triggle** is designed to work hand-in-hand with the animation classes from **[{css}animation](https://github.com/yesiamrocks/cssanimation)**. 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:
```bash
npm install @hellouxpavel/cssanimation
```
Then import it in your JavaScript:
```js
import "@hellouxpavel/cssanimation";
```
Or include it via CDN:
```html
<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.
## Getting Started
Trigger an animation on click.
To use **Triggle**, simply add `data-triggle-*` attributes to any HTML element you want to animate:
```html
<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.
## Integration Tips
- Core class `.cssanimation` is required (from [{css}animation](https://github.com/yesiamrocks/cssanimation)).
- Make sure the **[{css}animation](https://github.com/yesiamrocks/cssanimation)** styles are included in your project for the animation to work properly.
- Use `data-triggle-*` attributes only on the intended element β avoid duplication on deeply nested structures to prevent conflicts.
## Supported Triggers
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 |
## Attributes Reference
| 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 |
## Hover with Delay and Duration
This example shows how to trigger an animation on hover with custom timing and automatic reset:
```html
<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.
## Animates Once
This example shows how to trigger an animation only for a **single time**:
```html
<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>
```
- Use `data-triggle-once="true"` to ensure an animation only runs a **single time**, even if the triggering event happens again.
## Multiple Triggers
Trigger animations using more than one event by separating them with commas in the `data-triggle` attribute
```html
<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.
## Targeting Another Element
You can trigger animations on a different element using the `data-triggle-target` attribute:
```html
<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.
## Targeting Multiple Element
If you want to target multiple elements, separate them with commas in the `data-triggle-target=".box, #banner, #triggleTarget"` attribute:
```html
<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.
## Triggle Group Triggering
Trigger animations on multiple elements at once using `data-triggle-group`.
```html
<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
- The first element acts as the **trigger**.
- All elements sharing the same `data-triggle-group="cards"` will animate together.
- Each target can use its own animation class and settings.
> Great for triggering multiple cards, icons, or UI components in sync from a single interaction.
## Triggle Toggle Animation
Use `data-triggle-toggle="true"` to turn the animation class on and off with each trigger:
```html
<div
data-triggle="click"
data-triggle-class="ca__fx-moonFade"
data-triggle-toggle="true">
Click to toggle bounce
</div>
```
How it works
- On first click, the `ca__fx-moonFade` class is added.
- On second click, the same class is removed.
This cycle continues on every interaction.
> Useful for toggling active/inactive states with a single element.
## Triggle Scroll Animation
Animate elements as they scroll into view using `data-triggle-scroll="true"`:
```html
<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
- Triggers the `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.
## Triggle Scroll-Based Staggered Animation
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:
```html
<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:
```html
<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
- The **trigger element** activates the animation for all elements in the matching `data-triggle-group`.
- The `data-triggle-stagger="300"` adds a 300ms delay between each target's animation.
- Use `data-triggle-once="true"` if you want the animation only fires once when the group scrolls into view.
- Use `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.
## Triggle Chained Animation
Chain multiple animations by using `data-triggle-next` and control timing with `data-triggle-chain-delay`.
```html
<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:
- It animates with `ca__fx-swingIn`
- After `ca__fx-swingIn` finishes, triggle waits 500ms and then triggers `#step2`
- `#step2` animates using the `ca__fx-systemBootIn` class
Key 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.
## Chain Loop Example (data-triggle-chain-loop)
Create an infinite loop of chained animations between two or more elements.
```html
<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
- Clicking on `#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`.
- Because `data-triggle-chain-loop="true"` is set, the chain will repeat indefinitely.
> Useful for animated banners, instructional sequences, or continuous UI feedback loops.
## Keyboard Filter Example
Limit animations to specific key presses using `data-triggle-key`.
```html
<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:
- Single key match (a) `data-triggle-key="Enter,Escape"`
- Wildcards (a\* matches abc) `data-triggle-key="en*, arrow*"`
- Modifier keys (ctrl+s, shift+enter, alt+x) `data-triggle-key="ctrl+z, shift+a, alt+x"`
## Custom Events
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"));`
```html
<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>
```
## Manual Animation Trigger (Optional)
If you prefer programmatic control, you can manually trigger animations using `window.triggle.apply()`.
```js
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
- **Element** β The target DOM element
- **Class Name** β Animation class to apply
- **Reset** β Whether to remove the class after animation ends
- **Delay** β Optional delay before the animation starts (e.g., `"0.3s"`)
- **Duration** β Optional animation duration (e.g., `"1s"`)
- **Toggle** β Set to `true` to toggle the class on/off
> Ideal for triggering animations based on app logic, user input, or custom events.
## Cleanup
If you're using **Triggle** in a single-page app (SPA) or need to reinitialize after DOM changes:
```js
window.triggle.destroy(); // Removes all event listeners
window.triggle.init(); // Re-initializes all triggers
```
## Global Disable (Optional)
You can globally disable all **Triggle** animations, useful for accessibility, performance testing, or reduced motion preferences:
```js
window.__trg_TRIGGER_DISABLED = true;
```
To re-enable:
```js
window.__trg_TRIGGER_DISABLED = false;
window.triggle.init();
```
## Debug Mode
Enable debug mode to log internal behavior and aid in troubleshooting:
```js
window.__trg_DEBUG = true;
```
## Supported Passive Events
To improve performance, **Triggle** uses passive event listeners for the following triggers:
- `touchstart`
- `touchend`
- `scroll`
## Library Architecture Summary
- **Lightweight** and dependency-free β built with vanilla JavaScript
- Initializes quickly using `DOMContentLoaded` for efficient event binding
- Leverages native CSS for animation timing (`delay`, `duration`)
- Easy to integrate β just add `data-triggle-*` attributes and go
- Automatically cleans up using the `animationend` event
- Built with extensibility in mind β easy to add new trigger types or behaviors
## License
**Triggle** is proudly open-sourced under the [Apache License 2.0](./LICENSE). You can freely use it in personal, commercial, and creative projects.
Want a quick explanation? See the [License Summary β](./ABOUT-LICENSE.md)
## Contribute
We welcome all contributions β whether itβs fixing bugs, adding feature, improving docs, or sharing ideas!
- Found an issue? [Open a GitHub Issue](https://github.com/yesiamrocks/triggle/issues)
- Want to improve the library? [Submit a Pull Request](https://github.com/yesiamrocks/triggle/pulls)
- Have questions or feature ideas? [Start a Discussion](https://github.com/yesiamrocks/triggle/discussions)
Help us make **Triggle** even more magical for everyone.
## Need Help?
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!
- Report bugs or problems via [GitHub Issues](https://github.com/yesiamrocks/triggle/issues)
- Ask questions or get guidance in [GitHub Discussions](https://github.com/yesiamrocks/triggle/discussions)
Weβre happy to assist and make sure everything works smoothly in your setup.
## Support This Project
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:
- Keep the library up to date and bug-free
- Add new features and animation triggers
Every coffee counts β thank you for helping me keep creating. π
[](https://www.buymeacoffee.com/yesiamrocks)
## Become a Community Sponsor
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:
- Keep the library free and open for everyone
- Push out new triggers, animation packs, and ideas faster
- Write thoughtful dev/design content via my newsletter
π [Pixels & Projects with Pavel](https://www.linkedin.com/newsletters/pixels-projects-with-pavel-7093275757006782464/)
### As a Community Sponsor, you'll receive:
- A shoutout in the newsletter
- Your name or project proudly featured in the documentation and site
- My sincere gratitude for backing indie creativity on the web
Letβs build a more playful, animated web β together.
[](https://www.buymeacoffee.com/yesiamrocks/membership)
<br>
---
 [](https://www.linkedin.com/in/shafayetul/) [](https://twitter.com/yesiamrocks) [](mailto:yesiamrocks@gmail.com) [](https://www.linkedin.com/newsletters/pixels-projects-with-pavel-7093275757006782464/)