Scroll animations have now become standard on modern websites. They ensure that content is not immediately visible, but only appears once it enters the browser’s viewport.

Used correctly, such effects can improve the user experience and highlight important content more effectively. At the same time, the implementation should remain efficient and not result in unnecessary calculations with every scroll.

In this article, I’ll show you a simple solution using CSS and JavaScript that requires no additional libraries.

Why not just use the scroll event?

Many developers initially resort to the scroll event and check which elements are visible every time the browser moves.

Whilst this works for a small number of elements, it requires the browser to perform constant calculations.

The JavaScript API ` IntersectionObserver` offers a much more elegant solution. It automatically notifies us when an element enters the browser’s visible area.

This results in less code and, at the same time, better performance.

Preparing the HTML

First, we need an element that is to be animated.

<section class="animate">
    <h2>My headline</h2>
    <p> This content will be displayed as soon as it appears in the viewport. </p>
</section>

CSS for the animation

In its initial state, the element should be invisible and displayed slightly offset downwards.

.animate {
        opacity: 0;
        transform: translateY(40px);
        transition: opacity 0.6s ease, transform 0.6s ease;
    }

    .animate.is-visible {
        opacity: 1;
        transform: translateY(0);
    }

As long as the ‘is-visible’ class is missing, the element remains invisible.

As soon as the class is added, the animation starts automatically.

JavaScript with IntersectionObserver

Now let’s apply the ` animate` class to all the elements.

document.addEventListener('DOMContentLoaded', () =&gt; {
    const elements = document.querySelectorAll('.animate');

    const observer = new IntersectionObserver((entries) =&gt; {
        entries.forEach((entry) =&gt; {
            if (entry.isIntersecting) {
                entry.target.classList.add('is-visible');
            }
        });
    });

    elements.forEach((element) =&gt; {
        observer.observe(element);
    });
});

As soon as an element becomes visible, it is assigned the ‘is-visible’ class.

This triggers the previously defined CSS animation.

Run the animation only once

In most cases, the animation should only occur the first time the element appears.

To achieve this, the element can be removed from the observer once the animation has finished.

document.addEventListener('DOMContentLoaded', () =&gt; {
  
    const elements = document.querySelectorAll('.animate');
  
    const observer = new IntersectionObserver((entries, observer) =&gt; {

        entries.forEach((entry) =&gt; {

            if (!entry.isIntersecting) {
                return;
            }

            entry.target.classList.add('is-visible');

            observer.unobserve(entry.target);

        });

    });

    elements.forEach((element) =&gt; {
        observer.observe(element);
    });

});

[Translate to English:]

[Translate to English:] Das reduziert gleichzeitig den Ressourcenverbrauch, da bereits animierte Elemente nicht weiter überwacht werden.

[Translate to English:] Animation erst später starten

[Translate to English:] Mit dem Parameter threshold kann festgelegt werden, wann ein Element als sichtbar gilt.

[Translate to English:]

[Translate to English:] 

[Translate to English:]

[Translate to English:] Der Wert 0.2 bedeutet, dass etwa 20 Prozent des Elements sichtbar sein müssen, bevor die Animation ausgelöst wird.

Weitere Beispiele:

 

threshold: 0

 

Animation startet sofort.

 

threshold: 0.5

 

Animation startet erst, wenn ungefähr die Hälfte des Elements sichtbar ist.

[Translate to English:] Verschiedene Animationen unterstützen

[Translate to English:] Mit Datenattributen können unterschiedliche Animationen definiert werden.

[Translate to English:]

[Translate to English:] 

[Translate to English:]

[Translate to English:] 

[Translate to English:] Von links einblenden

[Translate to English:] 

[Translate to English:]

[Translate to English:] 

[Translate to English:] Von oben einblenden

[Translate to English:] 

[Translate to English:] Verzögerung einbauen

[Translate to English:] Oft sieht es besser aus, wenn mehrere Elemente leicht zeitversetzt erscheinen.

[Translate to English:]

[Translate to English:] 

[Translate to English:]

[Translate to English:] 

[Translate to English:]

[Translate to English:] Dadurch erscheinen die Elemente nacheinander.

[Translate to English:] Animationsdauer steuern

[Translate to English:] Auch die Dauer kann direkt über ein Datenattribut definiert werden.

[Translate to English:]

[Translate to English:] 

[Translate to English:]

[Translate to English:] 

[Translate to English:]

[Translate to English:] So lassen sich unterschiedliche Geschwindigkeiten verwenden, ohne zusätzliche CSS-Klassen anzulegen.

[Translate to English:] Komplette Lösung

[Translate to English:] 

[Translate to English:]

[Translate to English:] 

[Translate to English:] CSS

[Translate to English:] 
New comment

0 comments