Skip to content

Triggle makes controlling CSS animations simple with HTML attributes. Create interactive UIs, scroll effects & more. Get started easily!

License

Notifications You must be signed in to change notification settings

yesiamrocks/triggle

Repository files navigation

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