Skip to example

Stagger in random order

An example of staggering animations in a random order with stagger() in Motion.

JavaScript

Source code

<div class="stagger-stage">
    <ul class="example" aria-label="Squares staggered in a random order">
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
        <li><span class="stagger-delay"></span></li>
    </ul>
</div>

<script type="module">
    import { animate, stagger } from "motion"

    const items = document.querySelectorAll(".example li")
    const delay = stagger(0.05, { from: "random" })

    animate(
        items,
        { opacity: 1, scale: [0, 1] },
        { type: "spring", bounce: 0.4, delay }
    )

    // Label each item with the delay stagger() gives it
    items.forEach((item, i) => {
        const seconds = delay(i, items.length)
        item.querySelector(".stagger-delay").textContent = `${seconds.toFixed(2)}s`
    })
</script>

<style>
    #example-container {
        display: flex;
        flex: 1;
        align-self: stretch;
    }

    .stagger-stage {
        --ink: oklch(0.145 0.01 148);
        --paper: oklch(0.94 0.008 96);
        --plate: var(--paper);

        position: relative;
        display: flex;
        flex: 1;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        padding: 32px 16px;
        background-color: var(--ink);
        color: var(--paper);
    }

    ul.example {
        display: grid;
        grid-template-columns: repeat(6, auto);
        gap: clamp(4px, 1.4vw, 10px);
        margin: 0;
        padding: 0;
        list-style: none;
    }

    ul.example li {
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        box-sizing: border-box;
        width: clamp(38px, 8vw, 56px);
        aspect-ratio: 1;
        padding: clamp(4px, 1vw, 6px);
        background-color: var(--plate);
        color: var(--ink);
        opacity: 0;
    }

    .stagger-delay {
        font-family: var(--font-mono);
        font-size: 10px;
        font-variation-settings: "wght" 600;
        letter-spacing: 0.04em;
        line-height: 1;
    }

    @media (max-width: 420px) {
        .stagger-delay {
            font-size: 9px;
            letter-spacing: 0;
        }
    }
    }
</style>