viewmotion

Stagger

Animate lists, grids, and card groups with cascading delays. Add a data-stagger attribute to a container and each child with data-motion gets an automatic incremental delay.

Basic usage

<div data-stagger='{"delay":100,"step":80}'>
  <div data-motion='{"preset":"fade-up"}'>Card 1</div>
  <!-- effective delay: 100ms (base delay) -->
  <div data-motion='{"preset":"fade-up"}'>Card 2</div>
  <!-- effective delay: 180ms (100 + 1 × 80) -->
  <div data-motion='{"preset":"fade-up"}'>Card 3</div>
  <!-- effective delay: 260ms (100 + 2 × 80) -->
</div>

How it works

  1. Collects all direct children with data-motion
  2. Assigns each child an incremental delay: delay + (index × step)
  3. Adds the calculated delay to any existing delay on the child

Stagger options

ParameterTypeDefaultDescription
delaynumber0Base delay before the first child animates (ms)
stepnumber80Extra delay added per child (ms)

Using the helper

The stagger() helper generates the data-stagger attribute for you. It works in any environment that supports object spread on elements — JSX (React, Solid, Preact), Astro templates, Vue JSX:

import { motion, stagger } from "viewmotion";

<div {...stagger({ delay: 80 })}>
  <div {...motion({ preset: "fade-up" })}>A</div>
  <div {...motion({ preset: "fade-up" })}>B</div>
  <div {...motion({ preset: "fade-up" })}>C</div>
</div>;