Click Trigger
Play animations on click with toggle support for reverse and restart.
.onClick() plays a timeline when an element is clicked. By default it toggles between play and reverse on each click — first click plays forward, next click reverses.
Basic usage
Chain .onClick() after defining your animation. By default the click target is the first animated element.
import { Motion } from "@motion.page/sdk";
Motion("expand", ".card", {
to: { height: "240px", paddingBottom: "24px" },
duration: 0.4,
ease: "power2.inOut",
}).onClick(); Options
| Option | Type | Default | Description |
|---|---|---|---|
target | string | Element | First animated element | CSS selector or element that triggers the click. |
secondTarget | string | Element | — | Additional trigger element — clicking either target or secondTarget fires the animation. |
toggle | 'reverse' | 'restart' | 'play' | 'reverse' | What happens on the second click. 'reverse' plays backward, 'restart' replays from start, 'play' always plays forward. |
each | boolean | false | Give each matched element its own independent timeline instance. |
preventDefault | boolean | false | Call event.preventDefault() on the click event — useful when the trigger is a link or submit button. |
Toggle behavior
The toggle option controls what the second (and every even) click does:
'reverse'(default) — alternates play/reverse. Click once: plays forward. Click again: plays backward.'restart'— always replays from the start on each click. No reverse.'play'— always plays forward from current position. No reverse.
// Default — first click plays, second click reverses (accordion, drawer, etc.)
Motion("menu", "#nav-dropdown", {
from: { height: 0, opacity: 0 },
duration: 0.35,
ease: "power2.inOut",
}).onClick({ target: "#menu-btn", toggle: "reverse" });
// restart — replay from scratch on every click
Motion("flash", ".notification", {
to: { backgroundColor: "#ff4444", scale: 1.04 },
duration: 0.25,
ease: "power2.out",
}).onClick({ toggle: "restart" }); Separate click target
Use target to specify a different element as the trigger — the clicked element doesn’t have to be the animated element.
// Click the button to expand/collapse the panel
Motion("details", ".details-body", {
from: { height: 0, opacity: 0 },
duration: 0.4,
ease: "power2.inOut",
}).onClick({ target: ".details-toggle", toggle: "reverse" }); Add secondTarget when multiple elements should trigger the same animation:
// Click either the title or the icon to toggle the accordion
Motion("accordion", ".accordion-body", {
from: { height: 0 },
to: { height: "auto" },
duration: 0.35,
ease: "power2.inOut",
}).onClick({
target: ".accordion-title",
secondTarget: ".accordion-icon",
toggle: "reverse",
}); each — independent per-element instances
Without each, all matched elements share one timeline — clicking any card plays/reverses all of them together. With each: true, every element gets its own independent timeline.
// Without each — all cards toggle together
Motion("cards", ".card", {
to: { y: -8 },
duration: 0.3,
}).onClick({ toggle: "reverse" });
// With each — each card toggles independently
Motion("cards", ".card", {
to: { y: -8 },
duration: 0.3,
}).onClick({ each: true, toggle: "reverse" }); Click to rotate
Rotate an icon on each click — useful for chevrons next to dropdowns, arrows on toggles.
Motion("icon-spin", ".chevron", {
to: { rotate: 180 },
duration: 0.3,
ease: "power2.inOut",
}).onClick({ target: ".dropdown-btn", toggle: "reverse" }); Prevent default on links
When the click target is an <a> tag or a <button type="submit">, use preventDefault: true to stop the default browser action.
Motion("lightbox", ".lightbox", {
from: { opacity: 0, scale: 0.92 },
duration: 0.35,
ease: "power2.out",
}).onClick({
target: "a[data-lightbox]",
toggle: "reverse",
preventDefault: true,
}); Theme toggle
Animate a color transition driven by a toggle button:
Motion("theme", "#banner", {
to: { backgroundColor: "#1a1a2e", color: "#e0e0ff" },
duration: 0.5,
ease: "power2.inOut",
}).onClick({ target: "#dark-toggle", toggle: "reverse" }); Related
- Hover — react to mouse enter and leave
- Page Load Trigger — auto-play on DOM ready
- Timeline Control — play, pause, and seek timelines programmatically