Note
Il n’est pas utile de définir une animation-duration lorsqu’on utilise une
animation-timeline de type scroll() car il n’y a plus de notions de durée,
c’est la progression du défilement qui détermine l’avancement de l’animation.
Publié le :
Parmi les nouveautés CSS récentes, on retrouve les animations de scroll. Ces animations permettent de créer des effets visuels lors du défilement de la page ou d’un élément parent. Et tout cela, sans avoir besoin de Javascript.
Pour créer des animations, on utilise déjà la propriété animation qui est une version raccourcie de
animation-name, animation-duration, animation-timing-function, animation-delay, …
On peut définir le nom de l’animation, la durée, le délai, le nombre de répétitions, puis on peut définir les étapes de l’animation avec les @keyframes.
.animated {
animation: fadeIn 1s ease-in-out 0.5s infinite alternate;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
De base, une animation CSS s’exécute sur la timeline du document, les nouvelles spécifications définissent 2 nouveaux types de timeline :
Une timeline de progression de défilement est une timeline liée à la progression de la position de défilement d’un conteneur de défilement. La plage de défilement est convertie en pourcentage de progression de 0% à 100%.
Une timeline de progression d’affichage est une timeline liée à la progression de la position relative d’un élément particulier dans son conteneur de défilement. C’est la position relative d’un élément dans la zone de défilement qui détermine la progression. Dès que l’élément est visibible dans la zone, il y a intersection et la progression démarre, elle se termine dès que l’élément quitte cette zone.
En plus de la propriété animation, on va ajouter une nouvelle propriété animation-timeline.
Cette nouvelle propriété animation-timeline a été ajoutée pour fournir une chronologie de progression de l’animation en fonction du scroll de la page ou de la visibilité d’un élément.
Voici les valeurs principales possibles :
auto : l’animation est déclenchée sera celle par défaut du documentnone : l’animation n’est pas déclenchéescroll() : Scroll Progress Timelineview() : View Progress Timelinescroll-timeline-name.La fonction scroll() accepte les arguments <scroller> et <axis>.
Les valeurs acceptées pour l’argument <scroller> sont les suivantes :
Les valeurs acceptées pour l’argument <axis> sont les suivantes :
Il n’est pas utile de définir une animation-duration lorsqu’on utilise une
animation-timeline de type scroll() car il n’y a plus de notions de durée,
c’est la progression du défilement qui détermine l’avancement de l’animation.
Dans cet exemple, on va animer un carré en fonction du scroll de la page.
On peut aussi utiliser la valeur de progression fournie par la fonction scroll() sur d’autres propriétés CSS.
Dans l’exemple suivant, on affiche via une counter-reset et la fonction counter la valeur de la progression du scroll.
Parmi les valeurs possibles de la propriété animation-timeline, on peut aussi utiliser un identifiant pour déclencher l’animation.
Cela peut s’avérer utile lorsque vous ne ciblez pas un conteneur de défilement parent ou racine, ou lorsque la page
utilise plusieurs timelines ou lorsque les recherches automatiques ne fonctionnent pas.
Pour cela, il faut définir la propriété scroll-timeline-name sur le conteneur de défiler et lui donner un identifiant unique.
(la valeur doit commencer par --).
.container {
scroll-timeline-name: --timeline1;
}
Pour modifier l’axe à suivre, on déclare la propriété scroll-timeline-axis sur le conteneur de défilement.
.container {
scroll-timeline-axis: x;
}
On peut combiner ces 2 propriétés avec scroll-timeline.
.container {
scroll-timeline: --timeline1 x;
} On peut ensuite utiliser cet identifiant dans la propriété animation-timeline pour déclencher l’animation.
.animated {
animation-timeline: --timeline1;
}
Voici un exemple, où l’animation est déclenchée par un identifiant spécifique déclaré sur un élément conteneur.
Notez que même pour les timelines de défilement nommées, la recherche du sujet au conteneur de défilement n’est effectuée que sur les ancêtres. Nous verrons par la suite, qu’il est possible de déclencher l’animation sur un conteneur qui n’est pas forcément un ancêtre.
Pour créer une timeline de progression de vue , on va utiliser la fonction view() avec les arguments <axis> et <view-timeline-inset> qui correspondent respectivement à l’axe de progression et à la plage de progression.
Par défaut, l’animation est associée à toute la plage de la timeline, dès que l’élément entre dans la zone, l’animation démarre et se termine dès que l’élément quitte complètement la zone.
La fonction view() permet de déclencher l’animation en fonction de son apparition dans la zone de défilement.
C’est la position relative d’un sujet dans cette zone de défilement qui détermine la progression.
On peut définir la position de déclenchement de l’animation en fonction de la visibilité de l’élément.
Dans cet exemple, on fait apparaitre une image sans préciser de position particulière dans la fonction view().
C’est donc l’apparition de l’image dans la page qui déclenche l’animation.
On constate que l’image apparait dès qu’elle commence à être visible dans la page. L’opacité démarre à 0% et se termine à 100% mais seulement lorsque l’image quitte l’écran. Ce n’est pas forcément le comportement que l’on souhaite avoir, on aimerait que lorsque l’image est entièrement visible, l’opacité soit à 100%.
La fonction view() peut prendre différents arguments pour définir la position de déclenchement de l’animation.
Par exemple, on peut lui fournir directement des valeurs en pixels et faire apparaitre l’image dès que 100px est visible dans la zone de défilement.
img {
animation-timeline: view(200px 100px);
}
Il existe 2 autres propriétés pour gérer le décalage de l’animation : animation-range-start et animation-range-end (version courte animation-range).
Voici les différentes valeurs de plages de progression :
Voici un visualiseur de plages de progression d’affichage, il permet de bien comprendre les différentes valeurs possibles et ce qu’elles permettent de faire :
img {
animation: fadein linear 0.5s forwards;
animation-timeline: view();
animation-range: cover 0% contain 50%;
}
Dans cet exemple, l’animation démarre lorsque le début de l’image apparait et se termine lorsque le haut de la zone de sortie qui est positionnée à 50%.
Comme pour les timelines de progression de défilement, on peut utiliser une timeline nommée :
img {
view-timeline-name: --fadein-image;
view-timeline-axis: block;
animation: fadein linear 0.5s forwards;
animation-timeline: --fadein-image;
animation-range: cover 0% contain 50%;
}
Il est possible de définir les plages directement au niveau des @keyframes, cela permet de les animer sur une seule animation. Dans cet exemple, on a une animation sur le défilement d’apparition des images dans un conteneur avec une animation de sortie et d’entrée.
@keyframes animate-in-and-out {
entry 0% {
transform: translateY(200%) scale(0);
}
entry 100% {
transform: translateY(0) scale(1);
}
exit 0% {
transform: translateY(0) scale(1);
}
exit 100% {
transform: translateY(-200%) scale(0);
}
}
.projects__img {
animation: ease-in-out animate-in-and-out forwards;
animation-timeline: view();
}
On l’a vu dans les précédents exemples, le mécanisme de recherche des timelines nommées est limité aux ancêtres.
Il est toutefois possible d’animer un élément qui n’est pas enfant de la zone de défilement avec la propriété timeline-scope.
Cette propriété permet d’élargir la portée de la zone de défilement de la timeline nommée.
Dans cet exemple, on a un élément de défilement et un autre élément qui affiche la progression de défilement. Ces 2 éléments étant adajcents, on élargit le scope de la timeline au body afin que le mécanisme de recherche puisse s’effectuer.
La compatibilité est encore limitée, mais il est préférable d’utiliser les animation-timeline avec la règle @supports.
@supports (animation-timeline: scroll()) {
}
Il existe également des librairies Javascript comme Lax.js ou le polyfill “officiel” ScrollTimeLine pour gérer les compatibilités.