webdevpuneet.com

Motion One Spring Cards — Free Spring-Physics Card Grid Snippet

Motion One Spring Cards · Cards · Plain HTML, CSS & JS · Live preview

CategoryCards

Copy & paste

Source Code

Requires
<section class="msc-wrap">
  <header class="msc-head"><h1>Team Snapshot</h1><p>Hover a card, or drag one sideways — every motion here is Motion One's spring easing, not a linear or bezier curve.</p></header>
  <div class="msc-grid" id="mscGrid">
    <div class="msc-card" data-drag="true"><span class="msc-avatar" style="background:#6366f1">M</span><h3>Maya Chen</h3><p>Product Design</p></div>
    <div class="msc-card" data-drag="true"><span class="msc-avatar" style="background:#ec4899">R</span><h3>Ravi Patel</h3><p>Engineering</p></div>
    <div class="msc-card" data-drag="true"><span class="msc-avatar" style="background:#22c55e">S</span><h3>Sofia Reyes</h3><p>Growth</p></div>
    <div class="msc-card" data-drag="true"><span class="msc-avatar" style="background:#f59e0b">J</span><h3>Jamal Okafor</h3><p>Research</p></div>
  </div>
  <button class="msc-shuffle" id="mscShuffle">Shuffle in ↻</button>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Spring-based easing
spring({ stiffness, damping }) replaces bezier curves entirely.
Staggered entrance
stagger(0.08) delays each card's animation in sequence.
Snappy hover pop
Higher stiffness, lower damping gives a lively overshoot.
Pointer-driven drag
Cards drag horizontally and rotate slightly while dragging.
Spring drag-back
Releasing a card springs it back to center, not an instant snap.
Replayable shuffle
A button fades cards out then replays the staggered entrance.
Tiny dependency
Motion One's core is a few KB, built on the native WAAPI.
No build step needed
Loaded as a UMD global straight from a CDN script tag.

About this UI Snippet

Motion One Spring Cards — Spring Physics Entrances, Hover Pops & Drag-Back with Motion One

Screenshot of the Motion One Spring Cards snippet rendered live

Most CSS and JS animation relies on easing curves — bezier functions that approximate motion but never quite capture the springy overshoot-and-settle of a real physical object. This snippet uses Motion One, a small (under 5KB core) animation library built directly on the native Web Animations API, to drive card entrances, hover states, and drag interactions entirely with spring() easing instead of duration-based curves.

Why spring easing instead of bezier curves

A cubic-bezier easing curve is defined by four fixed control points and always takes the same shape regardless of how far an element travels. A spring, by contrast, is defined by physical parameters — stiffness and damping — and its motion emerges from simulating those forces frame by frame. This means a spring naturally travels faster over a longer distance and settles at a consistent, physical rate, which is why UI built with real device-like motion (iOS, native apps) tends to feel more responsive than web UI relying purely on timed curves. Motion One's spring() helper exposes this as a drop-in easing option for its animate() calls, so this snippet uses the exact same pattern as Scroll Reveal Grid's stagger, just with spring physics instead of a power curve.

Staggered spring entrance

On load, animate(cards, {...}, { delay: stagger(0.08), easing: spring({ stiffness: 220, damping: 18 }) }) animates every card's opacity, scale, and y-offset together, with each card's start delayed by 0.08s more than the previous one via Motion One's stagger() helper — the same staggered-wave idea as a GSAP-based reveal, but expressed with a two-line API and no separate plugin.

Hover pop and drag-back

Hovering a card triggers a snappier spring (stiffness: 300, damping: 14) that lifts and scales it slightly — high stiffness with low damping produces a small overshoot, giving the hover a lively "pop" rather than a flat linear lift. Dragging a card horizontally via pointer events, then releasing it, animates it back to x: 0, rotate: 0 using another spring — so letting go of a card doesn't just snap it back instantly, it bounces back the way a card on a real desk would.

Loading Motion One from a CDN

This snippet loads Motion One's UMD build directly via a <script> tag from jsDelivr, which exposes a global Motion object with animate, stagger, and spring — no bundler or import statement required, matching how this snippet library loads other CDN-based effects. If you're working in a module-based project instead, the same functions are available as named exports from the motion npm package or its ESM CDN build.

Customizing it

Tune stiffness/damping for snappier or looser motion (higher stiffness = faster, lower damping = more bounce), change the stagger delay, or swap the horizontal-only drag for a full 2D drag using Motion One's built-in drag utilities. Pair this with Feature Cards or a Product Card grid for a livelier catalog entrance.

Step by step

How to Use

  1. 1
    Add the Motion One CDNInclude the motion.js UMD build from the CDN panel — it exposes a global Motion object.
  2. 2
    Paste HTML, CSS, and JSA team card grid and a shuffle button render.
  3. 3
    Watch the entranceCards spring in with a staggered 0.08s delay between each.
  4. 4
    Hover a cardIt springs up and scales slightly with a snappy pop.
  5. 5
    Drag a card sidewaysRelease it — it springs back to center with a slight bounce.
  6. 6
    Click Shuffle inCards fade out quickly, then replay the staggered spring entrance.

Real-world uses

Common Use Cases

Team and about pages
Introduce a team card grid with spring physics instead of easing curves, using stagger(0.08) to delay each card in turn.
Product catalogue entrances
Animate a product card grid so each item pops in with a believable overshoot and settle, defined by stiffness and damping.
Feature showcases
Give feature cards a physical, tactile hover pop, with higher stiffness and lower damping for a lively bounce.
Draggable sortable boards
Use the drag and spring-back pattern for kanban-style boards, where cards rotate slightly while dragged horizontally.
Onboarding and testimonial rotators
Make onboarding card stacks feel physical, or pair with a testimonial card for a spring-driven review carousel.

Got questions?

Frequently Asked Questions

stiffness controls how strongly the spring pulls toward its target — higher values move faster and more urgently. damping controls how much the motion is resisted as it approaches the target — lower damping allows more oscillation and overshoot before settling, higher damping approaches smoothly with little or no bounce. Motion One simulates these forces frame by frame rather than interpolating along a fixed curve, which is why the resulting motion looks different depending on how far the element travels.

Motion One is a much smaller library (a few KB versus GSAP's larger core plus plugins) built directly on the browser's native Web Animations API, which makes it a good fit when spring easing and simple entrance/hover/drag animations are all you need. GSAP remains the stronger choice for complex timelines, scroll-triggered sequencing, or SVG morphing — see Scroll Reveal Grid for a GSAP-based example doing exactly that.

Pointer events (pointerdown/pointermove/pointerup) track horizontal movement and directly set a translateX/rotate transform on the card while dragging, giving instant 1:1 feedback. On pointerup, Motion One's animate() call takes over, animating x and rotate back to 0 using spring() easing — so the release feels like a physical snap-back rather than an abrupt jump.

Yes. This snippet loads the UMD build via a <script> tag so animate, stagger, and spring are available as the global Motion object with no bundler. In a module-based project, install the motion npm package and import { animate, stagger, spring } from 'motion' directly, or import from an ESM CDN like esm.sh/motion if you're not using a bundler but want ES module syntax.

Import animate, stagger, and spring from the motion package (or reference the CDN global if not bundling), then call animate() inside a mount effect (useEffect, onMounted, or ngAfterViewInit) targeting refs to your card elements rather than querySelectorAll. Attach the pointer event handlers as React/Vue/Angular event bindings instead of addEventListener, keeping the same spring() easing values.