Back to Dictionary
Page & View Transitions
●●●Requires Setup
Advanced

Parallax Scroll

Background elements move at a different speed than foreground elements while scrolling, creating an illusion of 3D depth and immersion.

Use

Marketing landing pages

Avoid

Data-heavy dashboards

Safer Alternative

No safer default listed.

Risk Level

Low risk

Live Demo

Explore

Scroll to reveal

01
Depth

Parallax Effect

Different scroll speeds create the illusion of depth. Foreground moves fast, background moves slow.

What It Is

Background elements move at a different speed than foreground elements while scrolling, creating an illusion of 3D depth and immersion.

When to Use

  • Marketing landing pages
  • Editorial feature stories
  • Hero sections with rich photography

When NOT to Use

  • Data-heavy dashboards
  • If it causes text readability issues

Configuration Tips

  • 01Keep the speed difference subtle (e.g., background moves 20-30% slower than foreground)
  • 02Use hardware-accelerated transforms (translate3D) rather than background-position

You've Seen It In

AppleStripeNike

AI Implementation Prompts

Move from a fast scaffold to production details, then tune timing and edge states.

Add a parallax scrolling effect to my hero image, so it moves slower than the rest of the page.

Reference Implementation

The same implementation approach used by the live preview, kept compact enough to inspect and adapt.

"use client";
import { useRef, useEffect } from 'react';
import { motion, useScroll, useTransform } from 'framer-motion';

export function ParallaxScrollDemo({ isPlaying = false }: { isPlaying?: boolean }) {
    const containerRef = useRef<HTMLDivElement>(null);

    const { scrollYProgress } = useScroll({
        container: containerRef,
    });

    "text-stone-400 italic">// Background moves slower
    const yBg = useTransform(scrollYProgress, [0, 1], ["0%", "50%"]);
    "text-stone-400 italic">// Foreground shape moves faster
    const yShape = useTransform(scrollYProgress, [0, 1], ["0%", "-100%"]);
    "text-stone-400 italic">// Top text moves slightly down
    const yText = useTransform(scrollYProgress, [0, 1], ["0%", "30%"]);

    useEffect(() => {
        if (!isPlaying || !containerRef.current) return;
        const speed = 1.5;
        let pos = 0;
        let direction = 1;

        const interval = setInterval(() => {
            if (!containerRef.current) return;
            pos += speed * direction;
            if (pos > 800) direction = -1;
            if (pos <= 0) direction = 1;
            containerRef.current.scrollTop = pos;
        }, 16);

        return () => clearInterval(interval);
    }, [isPlaying]);

    return (
        <div className="relative flex h-64 w-full items-center justify-center overflow-hidden rounded-2xl bg-white p-4 shadow-sm ring-1 ring-stone-200">
            {"text-stone-400 italic">/* Scrollable Container */}
            <div
                ref={containerRef}
                className="w-full max-w-sm h-56 overflow-y-scroll rounded-xl shadow-lg relative bg-stone-900 hide-scrollbar"
                style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
            >
                {"text-stone-400 italic">/* Parallax Background */}
                <motion.div
                    className="absolute inset-0 w-full h-[150%] z-0 origin-top pointer-events-none"
                    style={{ y: yBg }}
                >
                    {"text-stone-400 italic">/* Subtle grid pattern for background to make movement visible */}
                    <div className="absolute inset-0 opacity-10"
                        style={{ backgroundImage: 'radial-gradient(circle at center, white 1.5px, transparent 1px)', backgroundSize: '32px 32px' }}
                    />
                </motion.div>

                {"text-stone-400 italic">/* Scroll Content */}
                <div className="relative z-10 p-8 h-[1000px] flex flex-col justify-start">
                    {"text-stone-400 italic">/* Decorative Image Container */}
                    <motion.div
                        className="relative w-48 h-40 mt-8 rounded-2xl overflow-hidden shadow-xl"
                        style={{ y: yText }}
                    >
                        <div
                            aria-hidden="true"
                            className="absolute inset-0 h-[150%] bg-cover bg-center"
                            style={{
                                top: '-25%',
                                backgroundImage: "url('https:">//images.unsplash.com/photo-1549880338-65ddcdfd017b?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80')"
                            }}
                        />
                        <div className="absolute inset-0 bg-gradient-to-t from-stone-900/80 to-transparent" />
                        <div className="absolute bottom-4 left-4 right-4">
                            <h2 className="text-lg font-bold text-white mb-1">Explore</h2>
                            <p className="text-white/70 text-xs">Scroll to reveal</p>
                        </div>
                    </motion.div>

                    {"text-stone-400 italic">/* Floating Floating Element */}
                    <motion.div
                        className="w-32 h-32 ml-auto mt-20 mb-[200px] relative"
                        style={{ y: yShape }}
                    >
                        <div className="absolute inset-0 bg-white/10 backdrop-blur-md border border-white/20 rounded-2xl shadow-2xl flex flex-col items-center justify-center p-4">
                            <div className="w-12 h-12 rounded-full border border-white/30 flex items-center justify-center mb-3">
                                <span className="text-white text-xl font-light">01</span>
                            </div>
                            <span className="text-xs text-white/80 font-medium tracking-wider uppercase">Depth</span>
                        </div>
                    </motion.div>

                    <div className="mt-auto bg-stone-800/90 backdrop-blur-xl border border-stone-700/50 p-6 rounded-2xl shadow-2xl mb-12">
                        <div className="flex items-center gap-3 mb-3">
                            <div className="w-2 h-2 rounded-full bg-emerald-400" />
                            <h3 className="font-semibold text-white text-sm">Parallax Effect</h3>
                        </div>
                        <p className="text-xs text-stone-400 leading-relaxed">
                            Different scroll speeds create the illusion of depth. Foreground moves fast, background moves slow.
                        </p>
                    </div>
                </div>
            </div>
        </div>
    );
}