DEV Community

Cover image for How to make on-scroll animations in JavaScript and CSS
Andrew B
Andrew B

Posted on

How to make on-scroll animations in JavaScript and CSS

Have you seen basically every single cool corporate website, and noticed that text slides up when you scrolled to it? (see Apple's website) Because it is so common, you would think that there would be many answers to this question, right? But, after scrolling through many online tutorials, I couldn't find an appear-on-scroll animation, so I made my own.

The HTML (Dun dun dun!!!)

The HTML is fairly straightforward. Just make an element

<p>Some text</p>
and attach the class id="animate-scroll" to it. Please note that you can change the class at any time, just make sure to change the HTML, CSS, and JS class references too!

The full HTML (note that you can change the element. I used <p> for simplicity reasons.):

<p id="animate-scroll"</p>
Enter fullscreen mode Exit fullscreen mode

The CSS

Now for the CSS. This part is easy. Copy the following code:

.animate-scroll {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

.animate-scroll.visible {
  opacity: 1;
  transform: translateY(0);
}
Enter fullscreen mode Exit fullscreen mode

What's going on here? The .animate-scroll class declares the animation. This is the code that actually makes the animation. You can make another one, but I made a slide-up fade-in animation because it is the most common one I've seen. The .animate-scroll.visible, however, shows the state of the element when the animation is over. If you change .animate-scroll, you should also change this. For instance, if you are changing size, you should put size:100%; or something. However, if you just want a simple tutorial on how to do this, then don't change anything.

The JavaScript

Copy this simple JavaScript:

document.addEventListener('DOMContentLoaded', () => {
    const elements = document.querySelectorAll('.animate-scroll');

    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.classList.add('visible');
            }
        });
    }, {
        threshold: 0.9
    });

    elements.forEach(element => {
        observer.observe(element);
    });
});
Enter fullscreen mode Exit fullscreen mode

Woah! That's a lot of code! What's happening! Let's break it down step-by-step.
Firstly, document.addEventListener('DOMContentLoaded', () => is detecting for if the content is loaded. This just runs the "function".
const elements = document.querySelectorAll('.animate-scroll'); This finds the class. Change this too if you are changing the class of the HTML and CSS.
const observer = new IntersectionObserver((entries) => { entries.forEach(entry => This detects if the element is in the viewport. If it isn't, then it will not animate it.
if (entry.isIntersecting) { entry.target.classList.add('visible');} This detects if the animation is over. If it is, then it adds .visible to the CSS. that is why it is there!
threshold: 0.9 This calculates how much of it is on the page before animating it. 0 is as soon as a pixel reaches the page. 1 is when it is about 25% of the way up the page. 2 is about 50%... I like to keep it at about 0.9 for a chance that the user sees the animation without hiding the text for too long.
elements.forEach(element => { observer.observe(element); This just observes the element. It's kind of pointless to explain. Is it on the page??? This handles that.

The final code...

Are you too lazy to read my amazing explanations? Here is all of the code.

HTML:

<p id="animate-scroll">Your text here</p>
Enter fullscreen mode Exit fullscreen mode

CSS:

.animate-scroll {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

.animate-scroll.visible {
  opacity: 1;
  transform: translateY(0);
}
Enter fullscreen mode Exit fullscreen mode

JavaScript:

document.addEventListener('DOMContentLoaded', () => {
    const elements = document.querySelectorAll('.animate-scroll');

    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.classList.add('visible');
            }
        });
    }, {
        //The amount of screen displayed before animated. 0 is as soon as it appears on the page. 1 is a bit. 2 is...
        threshold: 0.9
    });

    elements.forEach(element => {
        observer.observe(element);
    });
});
Enter fullscreen mode Exit fullscreen mode

That's it! I hope you liked this deep dive into this. If you have any questions, comments or just want to talk to the famous guy who wrote this, leave a comment. I would love to see your suggestions!

Thanks for reading, CodeMonster

Top comments (0)