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 2/5 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
useScroll
hook to track scroll progressThe
useTransform
hook to convert scroll progress into position valuesThe
useSpring
hook to add physics-based smoothingThe
motion
component 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
useScroll
to track scroll progress both for the entire page and for individual elementsCreating a custom
useParallax
hook withuseTransform
to map scroll progress to position valuesApplying spring physics to scroll animations with
useSpring
for a more natural feelUsing the
motion
component 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.