Les effets d’apparition lors du défilement d’une page ajoutent une touche de dynamisme et de modernité à un site web. Pendant longtemps, la méthode classique consistait à écouter l’événement scroll de la fenêtre, une pratique souvent coûteuse pour la performance web en raison de son exécution continue.
Pourquoi abandonner l’événement scroll classique pour l’Intersection Observer ?
Historiquement, pour déclencher une animation lors du défilement, les développeurs utilisaient window.addEventListener('scroll', callback). Bien que fonctionnelle, cette méthode pose un problème majeur : l’événement est déclenché des dizaines de fois par seconde à chaque mouvement de molette.
Ce comportement surcharge le fil d’exécution principal (main thread) du navigateur, ce qui entraîne des saccades et dégrade considérablement la performance web.
L’API Intersection Observer résout ce problème. Elle délègue au navigateur la tâche de vérifier de manière asynchrone si un élément entre ou sort de la zone d’affichage (le viewport). Le code JavaScript ne s’exécute que lorsque l’état de visibilité change réellement, garantissant des animations fluides.
1. Préparer le terrain : HTML et CSS
Pour créer une animation CSS JS performante, le principe est simple : le CSS gère l’animation (les transitions), et le JavaScript se contente d’ajouter une classe au bon moment.
La structure HTML
Commençons par créer des éléments que nous souhaitons animer. Nous allons leur attribuer une classe reveal qui servira de point de repère.
<div class="content-section">
<h2 class="reveal">Mon premier titre animé</h2>
<p class="reveal">Un paragraphe qui apparaîtra en douceur au défilement.</p>
</div>Les styles CSS
Nous devons définir deux états : l’état initial (masqué) et l’état final (visible). Nous utiliserons les propriétés opacity et transform, car elles sont optimisées par les navigateurs et ne déclenchent pas de recalcul de la mise en page (reflow).
/* État initial : invisible et légèrement décalé vers le bas */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
/* État final : visible et à sa position d'origine */
.reveal-visible {
opacity: 1;
transform: translateY(0);
}2. Implémenter l’Intersection Observer en JavaScript
Maintenant que notre base est prête, nous allons écrire le script responsable de la détection visibilité élément.
Créer l’observateur
L’API fonctionne en instanciant un nouvel objet IntersectionObserver. Celui-ci prend en paramètre une fonction de rappel (callback) et un objet d’options.
const options = {
root: null, // null signifie que l'on observe par rapport au viewport
rootMargin: '0px', // Marge autour du root
threshold: 0.2 // Déclenchement quand 20% de l'élément est visible
};
const handleIntersect = function (entries, observer) {
entries.forEach(function (entry) {
// Si l'élément devient visible
if (entry.isIntersecting) {
// On ajoute la classe qui déclenche l'animation CSS
entry.target.classList.add('reveal-visible');
}
});
};
const observer = new IntersectionObserver(handleIntersect, options);Explication du code
- threshold : 0.2 : L’animation ne se déclenchera pas dès le premier pixel, mais uniquement lorsque 20 % de l’élément sera entré dans l’écran. Cela évite les déclenchements prématurés.
- entries : C’est un tableau contenant tous les éléments observés qui ont subi un changement d’état.
- entry.isIntersecting : Cette propriété booléenne vaut
truesi l’élément est actuellement visible selon le seuil défini.
Observer les éléments du DOM
Il ne reste plus qu’à cibler nos éléments HTML et à demander à notre observateur de les surveiller.
// On sélectionne tous les éléments ayant la classe .reveal
const elementsToReveal = document.querySelectorAll('.reveal');
// On boucle sur chaque élément pour l'ajouter à l'observateur
elementsToReveal.forEach(function (element) {
observer.observe(element);
});3. Optimiser l’effet d’apparition
Dans l’état actuel de notre code, si vous remontez la page, l’élément perdra-t-il son animation ? Non, car nous n’avons pas retiré la classe reveal-visible. Cependant, l’observateur continue de surveiller l’élément inutilement, ce qui consomme des ressources.
Jouer l’animation une seule fois
Pour une apparition au scroll classique, on souhaite généralement que l’animation ne se joue qu’une seule fois. Une fois l’élément affiché, nous devons demander à l’observateur d’arrêter de le surveiller grâce à la méthode unobserve().
const handleIntersect = function (entries, observer) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add('reveal-visible');
// On cesse d'observer cet élément précis
observer.unobserve(entry.target);
}
});
};Ainsi, votre script devient extrêmement léger : plus vous descendez dans la page, moins il y a d’éléments à observer.
Conclusion et autres cas d’usage
Vous savez désormais comment mettre en place un Intersection Observer au scroll pour gérer vos animations. Cette méthode sépare proprement la logique de détection (JavaScript) de la logique d’animation (CSS), tout en préservant l’expérience utilisateur.
Une fois cette API maîtrisée, de nombreuses autres possibilités s’offrent à vous. Le même principe de base vous permettra d’implémenter le chargement différé de vos images (lazy loading), de déclencher la lecture automatique d’une vidéo lorsqu’elle apparaît à l’écran, ou encore de concevoir un système d’infinite scroll pour charger de nouveaux articles automatiquement en bas de page.




