Click Trigger

Play animations on click with toggle support for reverse and restart.

.onClick() plays a timeline when an element is clicked. By default every click starts a fresh forward run. Set toggle: "reverse" when you want alternating forward and reverse clicks.

Basic usage

Chain .onClick() after defining your animation. By default the click target is the first animated element.

typescript
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 Separate element that performs the configured toggle action; the primary target always starts a fresh forward run.
toggle 'reverse' | 'restart' | 'play' 'play' Action for an even click on one target, or every click on secondTarget.
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' — alternates forward/reverse. Click once: starts forward. Click again: plays backward.
  • 'restart' — always replays from the start on each click. No reverse.
  • 'play' (default) — every primary-target click starts a fresh forward run. On a separate secondTarget, it resumes forward from the current position.
typescript
// reverse — 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.

typescript
// 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 one control should start the animation and another should perform its configured follow-up action:

typescript
// The title opens/restarts the accordion; the icon reverses it
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. To let clicking any matched element control that group timeline, pass the same selector as target. With each: true, every element gets its own independent timeline.

typescript
// Without each — all cards toggle together
Motion("cards", ".card", {
  to: { y: -8 },
  duration: 0.3,
}).onClick({ target: ".card", 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.

typescript
Motion("icon-spin", ".chevron", {
  to: { rotate: 180 },
  duration: 0.3,
  ease: "power2.inOut",
}).onClick({ target: ".dropdown-btn", toggle: "reverse" });

When the click target is an <a> tag or a <button type="submit">, use preventDefault: true to stop the default browser action.

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

typescript
Motion("theme", "#banner", {
  to: { backgroundColor: "#1a1a2e", color: "#e0e0ff" },
  duration: 0.5,
  ease: "power2.inOut",
}).onClick({ target: "#dark-toggle", toggle: "reverse" });