A parallax effect is a visual effect where the background or elements move at different speeds compared to the foreground, creating a sense of depth and immersion. This effect is commonly used in websites and apps to enhance user experience and engagement. In React, we can easily implement parallax scrolling with libraries like React Spring, Framer Motion, or by using the built-in scroll event to manipulate the position of elements as the user scrolls.
In this guide, we’ll walk through how to create parallax effects in React using React Spring.
1. Setting Up the Project
If you haven’t set up a React project yet, you can create one using:
npx create-react-app parallax-effect
cd parallax-effect
Next, install React Spring:
npm install @react-spring/web
2. Basic Parallax Effect with React Spring
We’ll start with a simple parallax effect where the background moves slower than the content as the user scrolls down the page.
Example: Simple Parallax Effect
import React, { useState, useEffect } from 'react';
import { useSpring, animated } from '@react-spring/web';
const ParallaxEffect = () => {
const [scrollY, setScrollY] = useState(0);
// Update scroll position on scroll
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// Create a spring animation for the parallax effect
const parallaxStyle = useSpring({
transform: `translateY(${scrollY * 0.3}px)`, // The parallax speed is controlled by the multiplier (0.3)
config: { tension: 170, friction: 26 },
});
return (
<div style={{ height: '200vh' }}> {/* Make the page tall to allow scrolling */}
<animated.div style={parallaxStyle} className="parallax-bg">
<h1 style={{ textAlign: 'center', color: '#fff' }}>Welcome to the Parallax Effect!</h1>
</animated.div>
<div className="content">
<p>Scroll down to see the parallax effect in action.</p>
</div>
</div>
);
};
export default ParallaxEffect;
Explanation:
scrollY
: Tracks the vertical scroll position.useEffect
: Listens for thescroll
event and updates the scroll position.useSpring
: Animates the background using atranslateY
property, which moves the background vertically based on the scroll position. The speed of the parallax effect is determined by the multiplier (0.3
in this case).animated.div
: This element is animated using the styles returned by theuseSpring
hook.
Styling (CSS)
/* App.css */
.parallax-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-image: url('https://source.unsplash.com/random');
background-size: cover;
background-position: center;
z-index: -1;
}
.content {
position: relative;
z-index: 1;
padding: 100px 20px;
text-align: center;
}
3. Parallax Effect with Multiple Layers
For more complex parallax effects, you can layer multiple elements, each with its own speed of movement, to create a deeper, more immersive effect.
Example: Multiple Layers with Different Parallax Speeds
import React, { useState, useEffect } from 'react';
import { useSpring, animated } from '@react-spring/web';
const MultiLayerParallax = () => {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// Parallax styles for each layer
const layer1Style = useSpring({
transform: `translateY(${scrollY * 0.2}px)`,
});
const layer2Style = useSpring({
transform: `translateY(${scrollY * 0.4}px)`,
});
const layer3Style = useSpring({
transform: `translateY(${scrollY * 0.6}px)`,
});
return (
<div style={{ height: '300vh' }}>
{/* Parallax Layer 1 */}
<animated.div style={layer1Style} className="layer-1">
<h1>Layer 1</h1>
</animated.div>
{/* Parallax Layer 2 */}
<animated.div style={layer2Style} className="layer-2">
<h1>Layer 2</h1>
</animated.div>
{/* Parallax Layer 3 */}
<animated.div style={layer3Style} className="layer-3">
<h1>Layer 3</h1>
</animated.div>
<div className="content">
<p>Scroll down to see different layers moving at different speeds.</p>
</div>
</div>
);
};
export default MultiLayerParallax;
Explanation:
- Multiple Layers: Here, we have three layers, each with a different parallax speed. The first layer moves at 20% of the scroll speed, the second at 40%, and the third at 60%.
useSpring
for Each Layer: Each layer has its own spring animation, creating the layered parallax effect.
Styling (CSS)
/* App.css */
.layer-1,
.layer-2,
.layer-3 {
position: fixed;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 3rem;
}
.layer-1 {
background-color: rgba(255, 99, 71, 0.6);
z-index: -3;
}
.layer-2 {
background-color: rgba(60, 179, 113, 0.6);
z-index: -2;
}
.layer-3 {
background-color: rgba(70, 130, 180, 0.6);
z-index: -1;
}
.content {
position: relative;
z-index: 1;
padding: 100px 20px;
text-align: center;
}
4. Parallax Effect with Image and Text Elements
You can also apply the parallax effect to individual text or image elements to create unique scrolling effects.
Example: Parallax Effect with Image and Text
import React, { useState, useEffect } from 'react';
import { useSpring, animated } from '@react-spring/web';
const ImageTextParallax = () => {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// Parallax animation for the image
const imageStyle = useSpring({
transform: `translateY(${scrollY * 0.5}px)`,
});
// Parallax animation for the text
const textStyle = useSpring({
transform: `translateY(${scrollY * 0.2}px)`,
});
return (
<div style={{ height: '200vh' }}>
<animated.div style={imageStyle} className="parallax-image">
<img src="https://source.unsplash.com/random/800x600" alt="Parallax" />
</animated.div>
<animated.div style={textStyle} className="parallax-text">
<h1>Beautiful Parallax Effect!</h1>
<p>Scroll to see the parallax effect in action.</p>
</animated.div>
</div>
);
};
export default ImageTextParallax;
Explanation:
- Image and Text Animations: The background image and text have different parallax speeds, giving the illusion of depth.
useSpring
for Each Element: We animate both the image and the text using separate spring animations to control their movement.
Styling (CSS)
/* App.css */
.parallax-image img {
width: 100%;
height: auto;
object-fit: cover;
}
.parallax-text {
position: relative;
z-index: 1;
padding: 100px;
color: white;
text-align: center;
}