Fade in animation on scroll with vanilla JavaScript and CSS Vanilla JSCSS

You can animate an element to fade-in when a user scrolls down to that element to make a webpage feel more dynamic. This is how to fade-in on scroll with vanilla JavaScript and CSS.

The first thing to do in order to fade elements in on scroll is decide how you are going to identify the elements that you want to animate. In this example I've added a class 'fade-in-up-on-scroll' to the element that I want to fade in and slide up.

<!-- HTML -->
<div class="fade-in-up-on-scroll">hi</div>

To show the CSS and JavaScript we're about to write in action, I've applied this effect to some of my code blocks on this page.

Next, in the CSS, we'll define a CSS keyframes animation which animates both opacity from 0 to 1 and a vertical transform translate declaration from an offset position back to the initial position. You can customise the from offset position in transform: translateY(50px); to any value you want.

We'll also create a class where we use this CSS keyframes animation. We will then add this class to the element depending on the scroll position in order to animate the elements at the right time. Here I have created a class called .fade-in-up which uses the animation shorthand declaration to define the animation duration, animation fill mode and the name of the animation to use.

/* CSS */
@keyframes fadeInUp {
  from {
    transform: translateY(50px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
.fade-in-up {
  animation: 0.75s both fadeInUp;
}

In the JavaScript, we'll need to select all of the elements on the page with our class 'fade-in-up-on-scroll'. We can do this with querySelectorAll() which returns a NodeList representing the elements. Then if there are instances of that class on the page, we'll add an event listener for the scroll event to capture when the user scrolls.

Then for each of the elements that we want to animate we'll need to check if the user has scrolled to that element's position on the page. We can do this by looping through the elements with forEach() and checking window.scrollY against element.offsetTop.

Since window.scrollY is based on the top of the viewport, we'll also want to account for the viewport height so the elements animate as they enter the bottom of the viewport not as they reach the top.

If the user has reached that element's position on the page, we'll add our CSS class .fade-in-up that uses the animation we defined. Since we already defined a CSS keyframes animation, just adding this class will animate the element.

We can also check if the user's scroll position is less than the element's position on the page, e.g. if the user has scrolled back up the page, and remove the class. Taking this extra step to remove the class after the user has scrolled back up above the element means that our animation will run again every time the user then scrolls back down the page rather than only once.

// JavaScript
const elementsToFadeInUpOnScroll = document.querySelectorAll(".fade-in-up-on-scroll");
if (elementsToFadeInUpOnScroll) {
  window.addEventListener("scroll", function(event) {
    elementsToFadeInUpOnScroll.forEach(function(element) {
      if (window.scrollY >= (element.offsetTop - window.innerHeight)) {
        element.classList.add("fade-in-up");
      } else {
        element.classList.remove("fade-in-up");
      }
    });
  });
}

Thanks for reading.
Ryan

Published on 30 Aug 2022
Last modified on 30 Aug 2023