Dans ce chapitre, on va découvrir les transitions et les animations en CSS. Ce sont deux mécanismes proches, mais ils ne répondent pas exactement au même besoin.
Une transition sert à animer le passage d'un état à un autre (par exemple au survol d'un élément) tandis qu'une animation sert à définir une séquence d'étapes que l'on peut rejouer librement.
Le principe des transitions
Une transition permet d'animer l'évolution d'une propriété entre une valeur de départ et une valeur d'arrivée.
Prenons un exemple simple :
.box {
transition-duration: 0.3s;
}
.box:hover {
transform: scale(1.5);
}
Ici, lorsque l'élément passe à l'état :hover, sa transformation ne change pas brutalement : elle évolue pendant 0.3s.
Les principales propriétés de transition
Une transition repose surtout sur quatre propriétés :
transition-propertytransition-durationtransition-timing-functiontransition-delay
transition-duration
Elle permet de définir la durée de la transition.
.box {
transition-duration: 300ms;
}
.box2 {
transition-duration: 0.3s;
}
Par défaut, la durée vaut 0s, donc il n'y a aucun effet visible.
transition-property
Par défaut, une transition s'applique à toutes les propriétés animables, ce qui revient à all. Mais on peut cibler uniquement certaines propriétés :
.box {
transition-property: transform;
transition-duration: 0.3s;
}
On peut aussi en indiquer plusieurs :
.box {
transition-property: transform, opacity;
transition-duration: 0.3s, 1s;
}
Dans cet exemple :
transforms'anime en0.3sopacitys'anime en1s
La courbe d'animation avec transition-timing-function
La propriété transition-timing-function permet de définir la manière dont l'animation progresse dans le temps.
.box {
transition-property: transform;
transition-duration: 1s;
transition-timing-function: ease;
}
Avec la valeur par défaut easer, l'animation démarre doucement, accélère, puis ralentit à la fin. C'est souvent la valeur la plus agréable visuellement.
Les courbes personnalisées
Il est aussi possible de définir sa propre courbe avec cubic-bezier().
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
Rassurez vous, il existe des sites comme cubic-bezier.com ou curveeditor qui vous permettent de générer ces courbes visuellement.
Transition et valeurs discrètes
Toutes les propriétés CSS ne peuvent pas être animées. Par exemple, display n'est pas animable :
.box {
display: none;
}
.wrapper:hover .box {
display: block;
}
Ici, l'élément apparaît d'un coup. Il n'y a pas de transition fluide possible car display change de manière discrète. Le changement de visibilité coupe aussi les transitions des autres propriétées.
transition-behavior
Pour remédier au problème on peut utiliser transition-behavior: allow-discrete; qui aide à mieux gérer ce genre de situation. Au lieu de passer en display: none immédiatement. L'élément passera en display: none; à la fin de la transition. Cela permet d'avoir un effet de disparition avec une transition.
@starting-style
Quand un élément apparait (si il passe d'un none à un autre type de display par exemple) ses transitions ne sont pas jouées. On peut dans ce cas définir explicitement un état de départ avec @starting-style.
@starting-style {
.box {
opacity: 0;
transform: scale(1);
}
}
L'utilisation du transition-behavior et du @starting-style n'a de sens que si l'élément change de display mais dans la plupart des cas les transition seront simple à définir et on se contentera d'ajouter de petites transitions pour rendre l'interface plus agréable.
En changeant par exemple la couleur d'un bouton au hover :
.btn {
transition: background-color 0.3s;
}
.btn:hover {
background-color: #1d5f43;
}
Le principe des animations CSS
Quand une transition ne suffit plus, on peut définir une animation complète grâce à @keyframes. Une animation permet de décrire plusieurs étapes dans le temps.
@keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
Ici, on crée une animation nommée spinner.
fromcorrespond au début de l'animationtocorrespond à la fin
On peut aussi utiliser des pourcentages :
@keyframes spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
Appliquer une animation à un élément
Une fois l'animation définie, on peut l'appliquer à un élément avec les propriétés animation-*.
.icon {
animation-name: spinner;
animation-duration: 1s;
}
Cela joue l'animation une seule fois sur une durée de 1s.
Les principales propriétés d'animation
Les propriétés les plus utiles sont :
animation-nameanimation-durationanimation-timing-functionanimation-delayanimation-iteration-countanimation-fill-modeanimation-direction
animation-iteration-count
Elle définit le nombre de répétitions.
.icon {
animation-name: spinner;
animation-duration: 1s;
animation-iteration-count: infinite;
}
Avec infinite, l'animation tourne sans fin. Pour un spinner, on ajoute généralement aussi :
.icon {
animation-timing-function: linear;
}
Cela évite les accélérations et ralentissements visibles.
animation-fill-mode
Cette propriété permet de contrôler l'état de l'élément avant ou après l'animation.
.box {
animation-fill-mode: both;
}
Les valeurs les plus utiles sont :
forwardsbackwardsboth
Par exemple, forwards permet de conserver l'état final de l'animation une fois qu'elle est terminée.
La propriété raccourcie animation
Comme pour transition, on peut tout condenser :
.icon {
animation: spinner 1s linear infinite;
}
Cette écriture est souvent la plus pratique.
Une animation peut avoir plusieurs étapes
Contrairement à une transition, une animation peut contenir autant d'étapes qu'on veut.
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.5);
}
75% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
Ici, l'élément :
- garde sa taille normale
- grossit
- rétrécit fortement
- revient à sa taille initiale
Ce type d'animation est impossible à exprimer proprement avec une simple transition.
Jouer une animation seulement dans certains cas
Une animation n'est pas obligée de tourner en permanence. On peut aussi la déclencher seulement sur un état particulier.
Par exemple :
.box:hover {
animation: pulse 1s;
}
Dans ce cas, l'animation se joue seulement au survol.
Cela peut être utile quand :
- l'animation est trop complexe pour être une transition
- on veut un effet ponctuel
- on veut attirer l'attention sur un élément
Le sens de lecture avec animation-direction
On peut aussi changer le sens de lecture de l'animation :
.box {
animation-direction: reverse;
}
Ou alterner automatiquement :
.box {
animation-direction: alternate;
}
Cela peut être pratique pour les allers-retours ou les mouvements répétitifs.
Transition ou animation : comment choisir ?
Le choix est généralement simple :
- s'il y a juste un passage d'un état à un autre, on utilise une transition
- s'il faut plusieurs étapes, une répétition infinie ou une séquence plus riche, on utilise une animation
En pratique, dans la majorité des interfaces, on utilise surtout des transitions :
transition: 0.3stransition: transform 0.3s easetransition: background-color 0.3s
Et on réserve les animations aux cas plus marqués :
- spinner de chargement
- pulse
- shake
- vibration