Skip to content

Scroll Velocity Skew

Skews its content based on how fast the page is being scrolled, relaxing back to flat at rest.

DOM + CSS1 dep1 file · 1 KB TSXreduced-motion aware

Probrutalisteditorial
Preview

Props

1
12

The source is part of Pro

$27/month or $179 once. See Pro

Requires framer-motion
"use client";

import { motion, useReducedMotion, useScroll, useSpring, useTransform, useVelocity } from "framer-motion";
import type { ReactNode } from "react";

export function ScrollVelocitySkew({
  children,
  sensitivity = 1,
  maxSkew = 12,
}: {
  children: ReactNode;
  sensitivity?: number;
  maxSkew?: number;
}) {
  const prefersReducedMotion = useReducedMotion();

  const { scrollY } = useScroll();
  const velocity = useVelocity(scrollY);

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Details

About this animation

Scroll Velocity Skew animates transform: skewY() — a compositor-cheap property — but derives it from scroll velocity rather than scroll position, so unlike typical parallax it sits at 0 when idle and only tilts while the user is actively scrolling fast. A native CSS scroll-driven animation (animation-timeline: scroll()) can link a transform to scroll position directly, but it has no notion of velocity — that derivative math (useVelocity) is the actual reason this needs Framer Motion rather than pure CSS. The non-obvious detail: the raw velocity signal is spiky, since it's a per-frame derivative of a discrete scroll position, so it's run through a second spring (useSpring) before being mapped to skew degrees — skipping that smoothing step makes the effect visibly jittery on every trackpad or wheel tick instead of fluid. The caveat: because it's inherently a multi-frame, always-reactive effect, treat it as an effect to disable outright under reduced motion rather than one to merely tone down.

Pairs well with

Pro
Pro