Niveau Niveau expert

Les Animations liées au scroll avec CSS

Articlecss

Publié par le (721 lectures)

transition range timeline ascenseur

Les animations liées au scroll (ou scroll-driven animations) constituent une nouvelle fonctionnalité CSS permettant de synchroniser des animations avec le défilement d'une page ou d'un conteneur. Cette solution native vient remplacer efficacement les scripts JavaScript habituels, avec une meilleure performance et une implémentation simplifiée de manière générale.

Apparition d'un bouton "scroll-to-top" lors du scroll de page. Source : Codepen

Syntaxe de base

Une animation liée au scroll n'en reste pas moins une animation au sens CSS du terme, elle nécessite donc un @keyframes et une propriété animation comme toute animation CSS classique. Ce sont les propriétés complémentaires animation-timeline et animation-range qui différencient ce type d'animation des autres.

@keyframes monAnimation {
  /* ici un scénario d'animation */
}
.element {
  animation: monAnimation linear auto both; /* Définit l'animation dans son ensemble */
  animation-timeline: scroll(); /* Définit le défilement comme référent */
  animation-range: 0 100%; /* Définit la plage de défilement pour l'animation */
}

Types d'animations possibles

La spécification CSS "Scroll-Driven Animations" définit deux modes d'animations, qui diffèrent par le moment auquel l'animation se déclenche :

  • Animation basée sur le scroll (Scroll Timeline) : L'animation se déclenche quand l'utilisateur scrolle au sein d'un conteneur défilable (ou la page entière)
  • Animation basée sur la vue (View Timeline) : L'animation se déclenche quand l'élément entre et sort de la vue d'un conteneur défilable (ou la page entière)

1. Animation basée sur le scroll (Scroll Timeline)

/* Animation liée au scroll du conteneur */
.element {
  animation-timeline: scroll();
}

La fonction scroll() accepte deux paramètres optionnels :

  • Le conteneur scrollable de référence : nearest (le plus proche, valeur par défaut), root (le document entier), self (l'élément lui-même s'il est scrollable)
  • L'axe de défilement : block (vertical, valeur par défaut), inline (horizontal), y (vertical), x (horizontal)
Animation de l'entête du site bretzel.alsacreations.com (animation de type "scroll")

2. Animation basée sur la vue (View Timeline)

.element {
  /* Animation liée à la vue du conteneur */
  animation-timeline: view();
}

La fonction view() n'accepte qu'un seul paramètre optionnel : celui de l'axe de défilement : block (vertical, valeur par défaut), inline (horizontal), y (vertical), x (horizontal).

Navigation du site goetter.fr lorsque chaque section entre dans le viewport (animation de type "view()")

Dans le détail : animation-range

La propriété animation-range définit les points de début et de fin de l'animation par rapport au défilement. Elle accepte plusieurs formats de valeurs :

1. Mots-clés de position

.element {
  animation-range: entry cover; /* Du moment où l'élément entre dans la vue jusqu'à ce qu'il soit entièrement visible */
  animation-range: cover exit; /* Du moment où l'élément est entièrement visible jusqu'à ce qu'il sorte de la vue */
  animation-range: entry exit; /* Du moment où l'élément entre dans la vue jusqu'à ce qu'il en sorte */
}

2. Mots-clés avec pourcentages

.element {
  /* L'animation commence quand 25% de l'élément est visible et se termine quand il est couvert à 75% */
  animation-range: entry 25% cover 75%;

  /* L'animation commence quand l'élément est visible à 50% et se termine quand il sort de la vue */
  animation-range: cover 50% exit;
}

L'excellent outil View Timeline Ranges Visualizer permet de bien se représenter visuellement les différents mots-clés cover, contain, entry, exit, etc.

3. Valeurs absolues

.element {
  /* Définit le début à 0% du scroll et la fin à 100% */
  animation-range: 0% 100%;

  /* Animation sur une portion spécifique du scroll */
  animation-range: 100px 700px;
}

Dans le détail : linear auto both

Les valeurs linear, auto et both sont généralement recommandées pour les scroll-driven animations :

animation: monAnimation linear auto both;
  • Le mot-clé linear assure une progression constante et prévisible liée au scroll et évite les accélérations/décélérations qui peuvent créer des effets indésirables,
  • Le mot-clé auto est nécessaire car il remplace la durée traditionnelle en secondes (valeur 0 par défaut) ici inutile,
  • Le mot-clé both est recommandé car il combine les effets de forwards et backwards et maintient l'état final de l'animation même si l'utilisateur arrête de scroller.

Animation basée sur un référent personnalisé

Les scroll-timelines personnalisées permettent de lier une animation au défilement d'un conteneur spécifique plutôt qu'au plus proche ou de la page entière.

⚠️ Attention : l'élément animé doit être un descendant du conteneur avec le scroll-timeline-name.

/* Définition du conteneur avec scroll */
.scroll-container {
  overflow-y: auto; /* scroll obligatoire sur le conteneur */
  scroll-timeline-name: --nom-du-conteneur; /* nom donné au référent */
  ...;
}

/* Éléments animés en fonction du scroll du conteneur */
.animated-element {
  animation: slideIn linear auto both;
  animation-timeline: --nom-du-conteneur; /* lié au conteneur référent */
  ...;
}

Support navigateurs et enrichissement progressif

Les animations liées au scroll en CSS sont encore en développement et ne sont pas supportées par tous les navigateurs. Pour assurer une expérience dégradée élégante sur les navigateurs ne reconnaissant pas les scroll-driven animations, @supports est la solution :

/* Animation déclenchée uniquement si supportée */
@supports (animation-timeline: scroll()) {
  .element {
    opacity: 0;
    animation: fadeIn linear auto both;
    animation-timeline: scroll();
    animation-range: entry 50% cover 50%;
  }
}

Un exemple concret : une barre de progression animée au scroll

Barre de progression de lecture lors du défilement de la page. Source : Codepen
<div class="progress">
  <div class="progress-bar"></div>
</div>
.progress-bar {
  --progress-color: hotpink;
  --progress-size: 40px;
  position: fixed;
  top: 0;
  width: 100%;
  height: var(--progress-size);
  background: var(--progress-color);
}

@supports (animation-timeline: scroll()) {
  .progress-bar {
    animation: scale linear auto both;
    animation-timeline: scroll(root);
    animation-range: 0 100%;
  }
  @keyframes scale {
    from {
      scale: 0 1;
    }
    to {
      scale: 1 1;
    }
  }
}

Accessibilité

Dans certaines conditions, les animations ne sont pas toujours les bienvenues. C'est le cas notamment pour les personnes souffrant de troubles liés au mouvement ou à l'attention. Il est donc impératif de respecter les préférences d'accessibilité de l'utilisateur et c'est là qu'intervient le média CSS prefers-reduced-motion.

La valeur reduce s'assure de ne pas déclencher d'animation lorsqu'elle n'est pas souhaitée :

@media (prefers-reduced-motion: reduce) {
  .animated-element {
    animation: none;
  }
}

Performances

Pour des raisons relativement évidentes, toute animation à l'écran peut se révéler coûteuse en performance. Il est donc important de suivre quelques bonnes pratiques :

.animation-optimisee {
  will-change: transform;
  animation: slide linear auto both;
  animation-timeline: scroll();
}

Quelques démos et cas pratiques

Parmi la foule de démos trouvées sur les internets, voici un petit panel pour aller encore plus loin et se faire une idée des possibilités offertes par cette nouvelle spécification CSS :

Conclusion

Les animations liées au scroll en CSS représentent une avancée majeure pour les animations web, offrant une solution à la fois native et performante pour concevoir des expériences interactives liées au défilement. Bien que le support navigateur soit encore en développement, cette technologie est promise à un bel avenir et mérite d'être considérée pour les projets modernes, à condition d'observer quelques recommandations utiles telles que la prise en compte de l'accessibilité et de la performance.

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.