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 :

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 :

Les valeurs acceptées pour l’argument <axis> sont les suivantes :

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 :

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%.

CSS Scroll View range end cover 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

Retour à la liste des articles
Github de Samuel Gomez Linkedin de Samuel Gomez Twitter de Samuel Gomez Instagram de Samuel Gomez
Allez en haut