npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

triggle

v1.5.6

Published

A lightweight CSS animation trigger library that animates elements on click, hover, enter and more.

Readme

Animate with Triggle — Simple Trigger-Based CSS Animation Control

Vanilla JS No Dependencies Optimized for Mobile NPM Downloads npm package size minified size License jsDelivr unpkg View Demo Made for {css}animation

Buy Me a Coffee Join 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 | Download via NPM | Check on jsDelivr | View on unpkg

Installation

Using NPM

npm install triggle

Then import it in your JavaScript:

// Default (unminified)
import "triggle";

// Optional: Use minified build explicitly
import "triggle/triggle.min.js";

Using CDN

<!-- 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. 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.

Getting Started

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.

Integration Tips

  • Core class .cssanimation is required (from {css}animation).
  • Make sure the {css}animation 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:

<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:

<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

<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:

<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:

<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.

<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:

<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":

<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:

<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

  • 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.

<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.

<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.

<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"));

<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().

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:

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:

window.__trg_TRIGGER_DISABLED = true;

To re-enable:

window.__trg_TRIGGER_DISABLED = false;
window.triggle.init();

Debug Mode

Enable debug mode to log internal behavior and aid in troubleshooting:

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. You can freely use it in personal, commercial, and creative projects.

Want a quick explanation? See the License Summary →

Contribute

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.

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!

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. 🙏

Buy Me a Coffee

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

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.

Join Membership


Built with ❤️ by Pavel LinkedIn Twitter Email Newsletter