
I’ve been wanting to explore more staggered grid animations, and this time I wanted to experiment with perspective, filters and typography. So today, I’m excited to share this little experiment with you. There are endless possibilities, and honestly, I’m struggling to find the right words to describe it… language can feel so limiting sometimes 🙂
We’ve explored scroll-based layout animations before, and also played around with perspective effects. This time, I wanted to use both concepts somehow in grids and on typography. The heart of this demos is the cylinder like 3D effect that the two columned grid has. It’s really interesting to think what kind of animations actually look harmonic when given a number of columns (or rows).
Anyway, I hope you like it! Feel free to explore the code and use this!
Note that in this demo, I’m using the GSAP’s SplitText plugin, available with GSAP Plus. In the repo, you’ll find the trial version included for you to explore. If you want to build on these effects or use them on a live website, make sure you are in the GSAP Club!
Thanks for checking by!
#Staggered #Grid #Animations #ScrollTriggered #Effects #Codrops
In this tutorial, we’ll explore how to create staggered grid animations with a 3D effect that are triggered by scrolling. By combining CSS animations, JavaScript, and the power of the Intersection Observer API, we can build engaging, interactive grid layouts that animate based on the user’s scroll position.
This effect is perfect for showcasing images, cards, or content in a way that draws attention and creates a visually compelling experience as the user scrolls down the page.
1. Understanding the Concept
The goal is to create a grid layout where each item appears one after the other, but with a slight delay, resulting in a staggered animation effect. This will be coupled with a 3D perspective to make the items feel as though they’re coming to life as the user scrolls. As each grid item enters the viewport, it will animate with a scale, translate, and rotate effect to create a dynamic 3D-like movement.
2. Setting Up the Grid Layout
We begin by setting up a basic HTML structure with a grid container that holds the grid items. Each grid item will be animated individually.
htmlCopy code<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<!-- Add more grid items as needed -->
</div>
Now, let’s style the grid with CSS. We’ll use CSS Grid for layout and apply a 3D perspective effect on the grid container.
cssCopy codebody {
margin: 0;
font-family: Arial, sans-serif;
background: #f0f0f0;
}
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
padding: 50px;
perspective: 1000px; /* Adds depth to the 3D effect */
}
.grid-item {
background: #3498db;
height: 200px;
border-radius: 10px;
transform-style: preserve-3d;
transition: transform 0.5s ease, opacity 0.5s ease;
}
Here, we’ve set up a basic grid system with 4 columns. The perspective property on the grid will affect how 3D elements within it are perceived, giving it a sense of depth when they are transformed.
3. Adding Scroll-Triggered Animations
The magic happens when we trigger animations based on the scroll position. To do this, we’ll use the Intersection Observer API. This will allow us to detect when a grid item enters the viewport and trigger the animation only when it becomes visible.
javascriptCopy codeconst gridItems = document.querySelectorAll('.grid-item');
const observerOptions = {
root: null, // observing relative to the viewport
rootMargin: '0px',
threshold: 0.1, // 10% of the item should be in view
};
const handleIntersection = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const item = entry.target;
item.classList.add('in-view');
observer.unobserve(item); // Stop observing after the animation starts
}
});
};
const observer = new IntersectionObserver(handleIntersection, observerOptions);
gridItems.forEach(item => observer.observe(item));
This script uses the Intersection Observer to detect when each grid item is in view. When an item is detected in the viewport, we add the in-view class, which will trigger the animation.
4. Defining the Animation
Now, let’s define the animations. When the grid item enters the viewport, we’ll scale and rotate it slightly in 3D space, giving it a pop-in effect. The staggered timing will be achieved by applying a delayed transform on each item.
cssCopy code.grid-item {
background: #3498db;
height: 200px;
border-radius: 10px;
transform-style: preserve-3d;
transition: transform 0.5s ease, opacity 0.5s ease;
opacity: 0;
transform: translateY(50px) rotateY(15deg);
}
.grid-item.in-view {
opacity: 1;
transform: translateY(0) rotateY(0deg);
}
/* Staggered animation delays */
.grid-item:nth-child(1) {
transition-delay: 0.1s;
}
.grid-item:nth-child(2) {
transition-delay: 0.2s;
}
.grid-item:nth-child(3) {
transition-delay: 0.3s;
}
.grid-item:nth-child(4) {
transition-delay: 0.4s;
}
/* More items will follow the same pattern */
In this CSS:
- The grid items start with an opacity of 0 and are translated down (
translateY(50px)) and rotated slightly (rotateY(15deg)). - Once the item enters the viewport (indicated by the
.in-viewclass), it becomes fully visible (opacity: 1) and resets its position and rotation (translateY(0) rotateY(0deg)). - The staggered effect is achieved by adding a delay to each item based on its order in the grid.
5. Enhancing the 3D Effect
To further enhance the 3D effect, you can modify the transform properties to simulate perspective-based depth. For example, you can adjust the rotateX or rotateZ axis for a more dynamic effect. Here’s an updated version of the animation that introduces some 3D rotation along the X axis:
cssCopy code.grid-item {
background: #3498db;
height: 200px;
border-radius: 10px;
transform-style: preserve-3d;
transition: transform 0.6s ease, opacity 0.6s ease;
opacity: 0;
transform: translateY(50px) rotateY(15deg) rotateX(10deg);
}
.grid-item.in-view {
opacity: 1;
transform: translateY(0) rotateY(0deg) rotateX(0deg);
}
This tweak will create a tilting effect as each item pops into view, further enhancing the perception of depth.
6. Conclusion
By combining CSS grid layouts, scroll-triggered animations, and 3D effects, you can create visually appealing, interactive experiences for your website. This technique not only adds aesthetic value but also engages users by responding to their scrolling actions.
With minimal JavaScript and pure CSS transitions, you can achieve sophisticated effects that make your website feel dynamic and modern. The best part is that these animations are highly customizable—adjust the timing, effects, and layout to fit your project’s needs.
7. Further Enhancements
Here are some ways you can extend this effect:
- Add Custom Easing: Modify the transition easing to make the animations feel more natural or exaggerated.
- Responsive Grid: Adjust the number of columns in the grid based on the viewport size for a responsive design.
- Interactive Content: Instead of just images, you could use this effect for interactive cards, product listings, or even text-bsed content.