
Valentin Descombes
Smooth Scroll Animations
Learn how to create beautiful scroll-triggered animations
Setting up the project
In this tutorial, we'll create smooth scroll animations using the Intersection Observer API. First, let's set up our project structure.
1mkdir scroll-animations2cd scroll-animations3touch index.html style.css script.js
Next, let's create a basic HTML structure for our animation elements.
Creating the HTML structure
Let's create a simple HTML structure with multiple sections that we'll animate as they scroll into view.
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="UTF-8">5<meta name="viewport" content="width=device-width, initial-scale=1.0">6<title>Smooth Scroll Animations</title>7<link rel="stylesheet" href="style.css">8</head>9<body>10<header>11<h1>Scroll Animations</h1>12<p>Scroll down to see the animations</p>13</header>1415<section class="animate-section">16<h2>Fade In</h2>17<div class="content">18<p>This content will fade in when scrolled into view.</p>19</div>20</section>2122<section class="animate-section">23<h2>Slide In From Left</h2>24<div class="content slide-left">25<p>This content will slide in from the left.</p>26</div>27</section>2829<section class="animate-section">30<h2>Slide In From Right</h2>31<div class="content slide-right">32<p>This content will slide in from the right.</p>33</div>34</section>3536<script src="script.js"></script>37</body>38</html>
💡 Tip
Make sure to add the "animate-section" class to any element you want to animate on scroll.
Adding JavaScript for scroll animations
Now let's add the JavaScript code that will power our scroll animations using the Intersection Observer API.
1// Select all elements with the animate-section class2const sections = document.querySelectorAll('.animate-section');34// Configure the Intersection Observer5const observerOptions = {6root: null, // Use the viewport as the root7threshold: 0.1, // Trigger when 10% of the element is visible8rootMargin: '0px 0px -50px 0px' // Add a negative bottom margin to trigger earlier9};1011// Create a new Intersection Observer instance12const observer = new IntersectionObserver((entries, observer) => {13entries.forEach(entry => {14// If the element is intersecting (visible)15if (entry.isIntersecting) {16// Add the 'animate' class to trigger the animation17entry.target.classList.add('animate');1819// Stop observing the element after it's animated20// Remove this line if you want the animation to replay when scrolling back up21observer.unobserve(entry.target);22}23});24}, observerOptions);2526// Start observing all sections27sections.forEach(section => {28observer.observe(section);29});
The highlighted lines show the most important configuration options for the Intersection Observer. You can adjust these values to control when the animations trigger as users scroll.
Adding CSS animations
Finally, let's add the CSS to create the animations that will be triggered when sections scroll into view.
1* {2margin: 0;3padding: 0;4box-sizing: border-box;5}67body {8font-family: Arial, sans-serif;9line-height: 1.6;10color: #333;11}1213header {14height: 100vh;15display: flex;16flex-direction: column;17justify-content: center;18align-items: center;19text-align: center;20padding: 2rem;21background: linear-gradient(135deg, #667eea, #764ba2);22color: white;23}2425/* Base styles for sections */26.animate-section {27min-height: 60vh;28display: flex;29flex-direction: column;30justify-content: center;31padding: 4rem 2rem;32border-bottom: 1px solid #eee;33}3435.animate-section:nth-child(odd) {36background-color: #f9f9f9;37}3839.content {40max-width: 800px;41margin: 0 auto;42opacity: 0;43transform: translateY(20px);44transition: opacity 0.8s ease, transform 0.8s ease;45}4647/* Animation styles - applied when the 'animate' class is added */48.animate-section.animate .content {49opacity: 1;50transform: translateY(0);51}5253/* Special animations for slide effects */54.slide-left {55transform: translateX(-100px) !important;56}5758.slide-right {59transform: translateX(100px) !important;60}6162.animate-section.animate .slide-left,63.animate-section.animate .slide-right {64transform: translateX(0) !important;65}
ℹ️ Note
The CSS transitions create smooth animations when elements come into view. The default animation is a fade-in with slight upward movement, while the slide effects add horizontal movement.