CSS : Animation Timeline
Introduction Introduction
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.
Rappel sur les animations clés Rappel sur les animations clés
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;
}
}
Timeline de progression Timeline de progression
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.
Propriété Propriété
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 Timeline- identifiant : l’animation est déclenchée par un identifiant spécifique déclaré sur un élément conteneur via la propriété
scroll-timeline-name
.
Détection de défilement Détection de défilement
La fonction scroll() accepte les arguments <scroller>
et <axis>
.
Les valeurs acceptées pour l’argument <scroller>
sont les suivantes :
- nearest: utilise le conteneur de défilement qui est l’ancêtre le plus proche (par défaut).
- root: utilise la fenêtre d’affichage du document comme conteneur de défilement.
- self: utilise l’élément lui-même comme conteneur de défilement.
Les valeurs acceptées pour l’argument <axis>
sont les suivantes :
- block: utilise la mesure de la progression sur l’axe de bloc du conteneur de défilement (par défaut).
- inline: utilise la mesure de la progression sur l’axe intégré du conteneur de défilement.
- y: utilise la mesure de la progression sur l’axe Y du conteneur de défilement.
- x: utilise la mesure de la progression sur l’axe X du conteneur de défilement.
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.
Cas simple Cas simple
Dans cet exemple, on va animer un carré en fonction du scroll de la page.
Valeur de progression Valeur de progression
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.
Timeline de progression nommée Timeline de progression nommée
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;
}
Note
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.
Note
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.
Détection de visibilité Détection de visibilité
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.
Cas simple Cas simple
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%.
Plages de progression avec animation-range Plages de progression avec animation-range
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 :
- cover: plage complète de la timeline de progression d’affichage.
- entry: plage pendant laquelle la zone principale entre dans la plage de visibilité de la progression d’affichage.
- exit: plage pendant laquelle la zone principale quitte la plage de visibilité de la progression d’affichage.
- entry-crossing: plage pendant laquelle la zone principale croise le bord de la bordure finale.
- exit-crossing: plage pendant laquelle la zone principale croise le bord de la bordure de début.
- contain: plage pendant laquelle la zone principale est entièrement incluse dans (ou couvre entièrement) sa plage de visibilité de la progression d’affichage dans la zone de défilement.
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 :
Exemple d’apparition d’image Exemple d’apparition d’image
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%.
Timeline de progression de visualisation nommée Timeline de progression de visualisation nommée
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%;
}
Associer plusieurs plages de la timeline à un keyframes Associer plusieurs plages de la timeline à un keyframes
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();
}
Associer à une timeline de défilement non ancêtre Associer à une timeline de défilement non ancêtre
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.
Compatibilités Compatibilités
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.
Sources et liens Sources et liens
- https://tympanus.net/codrops/2024/01/17/a-practical-introduction-to-scroll-driven-animations-with-css-scroll-and-view/
- https://codepen.io/tag/scroll-animation
- https://www.youtube.com/watch?v=oDcb3fvtETs&t=336s
- https://scroll-driven-animations.style/
- https://scroll-driven-animations.style/tools/view-timeline/ranges/
- https://developer.chrome.com/docs/css-ui/scroll-driven-animations
- https://www.youtube.com/watch?v=UmzFk68Bwdk
- https://www.youtube.com/watch?v=8-H0VTwa8vE