Parallax: Step-by-step tutorial

Matt Perry
In this tutorial, we're going to build the Parallax example step-by-step.
This example is rated intermediate difficulty, which means we'll spend some time explaining the Motion APIs we've chosen to use, but it assumes familiarity with JavaScript as a language.
Here's a live demo of the example we're going to be creating:
Introduction
The Parallax example shows how to create a scroll-linked animation where elements move at different speeds based on scroll position. It uses several features from Motion for React to create a dynamic, scroll-based UI:
The
useScrollhook to track scroll progressThe
useTransformhook to convert scroll progress into position valuesThe
useSpringhook to add physics-based smoothingThe
motioncomponent to apply these animations to DOM elements
Parallax effects are a popular technique for adding depth and visual interest to websites, and with Motion for React, implementing them becomes straightforward and performant.
Get started
Let's begin with the basic structure of our example:
This setup creates a scrollable page with five images stacked vertically. Each image takes up the full viewport height, and we're using CSS scroll snapping to ensure that each section aligns nicely with the viewport when scrolling.
Let's animate!
Now, let's add the animation logic that will create the parallax effect.
Import from Motion
First, let's update our imports to include all the Motion hooks we'll need:
Creating the parallax effect
Let's create a custom hook that will generate our parallax effect. This hook will take a MotionValue representing scroll progress and a distance value to determine how far the element should move:
This hook uses useTransform to map the scroll progress (which ranges from 0 to 1) to a position value that ranges from -distance to distance.
Tracking scroll for each image
Now, let's update our Image component to track scroll progress:
By setting target to the component's ref, this will track the progress of the element through the viewport.
We can then link that progress to y with our useParallax hook from before:
Creating a smooth progress indicator
Finally, let's update our Parallax component to add a progress bar that tracks overall scroll progress:
useScroll without any arguments will track the progress of the scroll of the entire page.
By passing this straight to the "progress", we get an animation that is linked very directly to scroll. We can smooth this with the useSpring motion value, passing this new motion value to "progress" instead:
By default, elements have a transform-origin that's in the center of the element. This means our progress bar will grow out from the center. We can grow out from (for instance) the left by setting originX to 0:
Conclusion
In this tutorial, we've learned how to create a parallax scrolling effect using Motion for React. The key concepts we've covered include:
Using
useScrollto track scroll progress both for the entire page and for individual elementsCreating a custom
useParallaxhook withuseTransformto map scroll progress to position valuesApplying spring physics to scroll animations with
useSpringfor a more natural feelUsing the
motioncomponent to apply dynamic styles based on scroll position
The combination of CSS scroll-snapping and Motion's scroll-based animations creates a modern, interactive experience that adds depth and visual interest to what would otherwise be a simple scrolling gallery.


