Valentin Dupas

💡 If this is the first course you read from me, please read this small thing : about my courses

Animations

Ouais je sais que la distiction entre "transition" et "animation" n'est pas immédiatement claire quand on en parle, parce que dans le langage courant on pourrais dire que "les transitions sont un type d'animation, puisque ça bouge c'est animé".

Mais quand on parle de CSS, ce sont deux choses distinctes.

Une transition décrit comment notre élément doit s'adapter quand on lui change ses propriétés.

Une animation est une chorégraphie de changements que l'on peut jouer, arrêter, avancer, reculer etc...

On créer une animation un peu comme on importe une police, sauf qu'on utilise @keyframes pour démarrer le bloc définissant l'animation.

Ci-dessous j'ai une animation avec un nom ridicule (pour vous montrer qu'on peut mettre le nom qu'on veux) qui décrit un départ avec une rotation nulle au début puis un tour complet à la fin.

@keyframes spiiiiin {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

#my-paragraph {
  animation-name: spiiiiin;
  animation-duration: 60s;
}

Hello

On remarquera deux choses.

  1. Ce coup-ci on a animation-name plutôt que transition-property parce que le nom que l'on spécifie n'est pas le nom de la propriété à surveiller mais le nom de l'animation à jouer.
  2. j'ai mis 60 secondes, c'est long!

Pourquoi 60 secondes? Parce que les animation, par défaut, se lancent quand la page s'ouvre, donc pour être à peu près sûr que vous la voyez je vous laisse pas mal de marge. Si vous l'avez raté vous pouvez toujours recharger la page.

Mais bon, on va voir comment palier à ça tout de suite avec ...

animation-iteration-count

Comme avec les transitions, des propriétés aditionnelles.

animation-iteration-count permet de spécifier combien de fois jouer l'animation, donc le bloc ci-dessous est exactement ce que l'on viens de voir sauf que l'animation va se jouer trois fois d'affilé au chargement de la page.

@keyframes spiiiiin {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

#my-paragraph {
  animation-name: spiiiiin;
  animation-duration: 60s;
  animation-iteration-count: 3;
}

Hello

C'est sympa, mais ce qui l'est encore plus est qu'on a une valeur spéciale qui est infinite qui permet de décrire que l'animation de se jouer en boucle

@keyframes spiiiiin {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

#my-paragraph {
  animation-name: spiiiiin;
  animation-duration: 60s;
  animation-iteration-count: infinite;
}

Hello

animation-timing-function

Comme pour les transitions, on peut définir l'accélération et la déccélération de la vitesse de lecture. On peut avoir l'impression que notre animation infinie ci-dessus s'arrête à certains moment parce que la fonction de timing par défaut est ease. Si je met linear alors la vitesse de lecture restera constante plutôt que d'approcher 0 aux alentours du début et de la fin.

@keyframes spiiiiin {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

#my-paragraph {
  animation-name: spiiiiin;
  animation-duration: 60s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

Hello

animation-direction

En plus de définir qu'une animation doit se jouer en boucle, c'est aussi pratique de pouvoir définir qu'une animation se joue un coup à l'endroit, un coup à l'envers.

Je vais raccourcir la durée de l'exemple pour que ce soit plus rapide de voir les va et viens.

@keyframes spiiiiin {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

#my-paragraph {
  animation-name: spiiiiin;
  animation-duration: 3s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-direction: alternate;
}

Hello

animation-direction peut prendre les valeurs suivantes:

  • normal : l'animation est jouée du début à la fin
  • reverse : l'animation est jouée de la fin vers le début
  • alternate : l'animation joue d'abord à l'endroit, puis à l'envers
  • alternate-reverse : l'animation joue d'abord à l'envers, puis à l'endroit

animation-fill-mode

Par défaut, les changements qu'applique une animation ne s'appliquent plus quand elle est finie

@keyframes black2red {
  0% {
    color: black;
  }
  100% {
    color: red;
  }
}

#my-paragraph {
  animation-name: black2red;
  animation-duration: 3s;
}

#my-second-paragraph {
  animation-name: black2red;
  animation-duration: 3s;
  animation-fill-mode: forwards;
}

je ne garde pas la couleur

moi si

animation-fill-mode peut prendre les valeurs suivantes :

  • forwards : on va retenir les propriétés telles qu'elles sont dans la dernière étape jouée. (donc 100% si la direction est normal ou 0% si la direction est reverse)
  • backwards : à l'inverse de forwards on gardera comme propriété finales les propriétés du début de l'animation (0% pour normal et 100% pour reverse)
  • both : on va garder toutes les modifications de valeurs, chaque changement écrasant les valeurs actuelles.

J'ai du mal à trouver une bonne explication pour l'usage de both, ça me parait être un bon moyen de se retrouver avec pleins de valeurs qui sortent d'un peu nul part.

Spoink

Dans beaucoup de cas on voudrait que les éléments s'animent quand ils arrivent dans notre champ de vision lorsequ'on scroll.

Pour ça je vous ai fait une petite librairie qui s'appelle SpoinkJS.

Un jour animation-timeline sera widely available et on pourra jeter spoink à la poubelle.