• 15 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 07/02/2024

Utilisez les propriétés de l'animation CSS

En surface, les keyframes ressemblent beaucoup à des transitions, mais avec des étapes supplémentaires en chemin. Peut-être que vous-même, vous ne voyez les keyframes que comme des transitions avec des étapes supplémentaires ? 

Mais détrompez-vous ! Les keyframes sont plus qu'un ensemble de valeurs !

Comprenez la différence entre @keyframes et transition

Comme nous venons de le voir avec notre barre de progression, les animations CSS avec keyframes ne se comportent pas comme des transitions. C'est normal : transitions et animations sont deux techniques ayant des logiques différentes, car elle ne répondent pas au même objectif.

Les transitions sont destinées à s'intégrer de manière subtile entre une valeur de départ et une valeur de fin. Telles que des valeurs  scale()  (d'échelle) différentes sur un bouton et sa pseudoclasse  :hover  :

Une animation CSS d'un bouton qui grossit avec des transitions

Ce bouton s'agrandit au fur et à mesure que nous le survolons, puis rétrécit lorsque la souris s'en éloigne, même si la transition n'est pas terminée.

Si nous appliquons les mêmes valeurs  scale()  via des @keyframes, le résultat obtenu est totalement différent. Voyez par vous-même :

Une animations du même bouton qui grossit avec des keyframes

Lorsque nous créons une transition, nous disons au navigateur d'aller et venir entre les valeurs assignées dans un sélecteur et les valeurs assignées à une pseudoclasse. Les @keyframes, quant à eux, lisent une série de valeurs définies. Une fois déclenchée, une animation avec keyframes progresse jusqu'à ce qu'elle soit terminée, ou jusqu'à ce qu'elle soit interrompue. 

Avec les keyframes, lorsque nous assignons notre animation progress-bar à l'état  :active  de notre bouton, l'animation n'existe que si l'état  :active  est déclenché. Lorsque l'on retire la souris, l'état  :active  disparaît de l'élément, et avec lui, de l'animation qui lui a été assignée. C'est pour cette raison que l'animation disparaît si brusquement lorsque l'on sort de l'état  :active.

            Une animation d'une barre de chargement qui disparaît lorsqu'elle est à 100 % 

Les transitions sont intrinsèquement liées à l'état d'un élément et aux différences dans ses valeurs assignées. Les propriétés et valeurs des keyframes sont quant à elles codées en dur, elles ne nécessitent qu'un événement pour les déclencher. Les pseudoclasses ne sont que l'une des options pour le faire. Dans ce chapitre, nous allons examiner une autre façon de déployer nos animations, ainsi que les propriétés supplémentaires à notre disposition pour concevoir des animations et des expériences utilisateur plus complexes.

Déclenchez vos animations dès le chargement de la page

Jusqu'à maintenant, nous avons appris à utiliser systématiquement une pseudoclasse pour déclencher nos animations. Car c'est effectivement la seule option en CSS lorsque nous utilisons des transitions. Mais avec les @keyframes, nous pouvons déclencher une animation dès le chargement d'un élément. 

Lorsque nous assignons une animation avec keyframe à un élément, il déclenchera l'animation au chargement dans le navigateur. Plutôt que d'appliquer notre animation de barre de progression à la pseudoclasse  :active  sur  .btn,  appliquons-la à  .progress__bar  en tant que telle :

.progress {
    &__bar {
        animation: progress-bar 1000ms;
    }
}

@keyframes progress-bar{
    0% {
        transform: scaleX(0);
        opacity: .1;
    }
    17% {
        transform: scaleX(.18);
    }
    24% {
        transform: scaleX(.4);
    }
    46% {
        transform: scaleX(.81);
    }
    85%,100% {
        opacity: 1;
    }
    100% {
        transform: scaleX(1);
    }
}

Maintenant, notre barre de progression se chargera dès que la page web sera chargée. Il n'est pas nécessaire d'interagir avec un bouton, ni d'ailleurs avec aucun autre élément. Le chargement de la page, et donc la barre de progression, est l'événement qui déclenche l'animation. Cela signifie que nous pouvons nous débarrasser de ce bouton :

<html>
<div class="container">
    <div class="progress">
        <div class="progress__bar"></div>
    </div>
</div>
</html>

Notre barre de progression se suffit maintenant à elle-même. Nous avons inséré un GIF pour indiquer quand la page se recharge :

Barre de chargement avec icone et sans délai

Superbe ! Notre animation... est animée !

Cher utilisateur, nous n'avons plus besoin de toi pour déclencher nos animations avec tes interactions. Plutôt pratique, n'est-ce pas ? Nous pouvons créer des animations sur notre site web pour introduire des éléments au fur et à mesure de leur chargement.

Ajoutez un délai à votre animation @keyframes

Le seul problème avec une animation qui démarre dès que la page se charge, c'est que... l'animation démarre dès la page se charge. Notre animation commence donc avant que nos visiteurs n'aient vraiment eu la chance de commencer à parcourir notre page.

Vous savez ce qui serait parfait ? Utiliser un délai de transition pour que notre animation attende un peu avant de démarrer. Malheureusement, la propriété  transition-delay  permet de retarder les transitions, et les transitions seulement. 😭

...Heureusement pour nous, il existe la propriété  animation-delay  !

Vous allez finir par croire que j'adore jouer avec vos émotions. Je vous dis qu'on ne peut pas, mais que finalement si. Ne m'en veuillez pas, j'essaie de vous faire découvrir la richesse des animations keyframes petit à petit, pour que puissiez pleinement en profiter 🤩

La propriété animation-delay  fonctionne comme  transition-delay, sauf qu'elle retarde uniquement les animations conçues avec des @keyframes. Elle accepte les valeurs en secondes :

.delay-seconds {
    animation-delay: 1s;
}

ou en millisecondes :

.delay-seconds {
    animation-delay: 1000ms;
}

Tout comme pour  transition-delay, nous pouvons indiquer la valeur de cette propriété dans la version abrégée "animation", en l'indiquant dans sa liste de valeurs. Ajoutons donc un court délai de 150 ms à l'animation de notre barre de progression :

.progress {
    &__bar {
        animation: progress-bar 1000ms 150ms;
    }
}

Maintenant, notre barre de progression attendra 0,15 secondes avant de commencer le chargement, donnant à nos visiteurs un moment pour remarquer notre barre de progression au chargement de la page :Barre de chargement avec icone et délai de 0.15s

Ça marche ! Mais...

L'effet ne marche pas vraiment, car rien n'est chargé... La barre se remplit, et puis... plus rien.

Choisissons du contenu à afficher une fois l'animation de la barre de progression terminée. Après tout, on est sur Internet, et Internet, c'est un peu le royaume des chats. Donc c'est parti pour une photo de chat. Alors, voyons voir ce que nous trouvons.

Enchaînez les animations

Photo de chat

🙌Yes ! Ça devrait faire l'affaire !

 Ajoutons une  div  pour notre photo de chat après notre  div .progress, ainsi que quelques paragraphes de texte :

<html>
    <p>Merci pour votre patience</p>
        <p>Voici votre chat</p>
</html>

Et utilisons la propriété  background-image  pour remplir la div avec notre nouvelle photo de chat, ainsi que quelques autres propriétés pour redimensionner et recadrer l'image et rendre le texte lisible :

.cat {
    width: 50vw;
    height: 30vw;
    position: absolute;
    overflow: hidden;
    background-image: url("https://bit.ly/2XJJLKn");
    background-size: cover;
    background-position: -20%;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    padding: .1rem;
    font-size: 4vw;
    font-weight: 900;
    color: white;
}

Si nous l'affichons dans le navigateur, nous voyons notre photo de chat... et pas grand-chose d'autre :

                                                   Image de chat

Pour le moment, notre div  .cat  couvre notre barre de progression, ce qui convient une fois la barre chargée. En revanche, nous ne souhaitons pas la voir tant que la barre n'a pas fini de se charger. Pour cela, créons un nouvel ensemble de @keyframes pour déplacer notre image hors de l'écran, jusqu'à ce que la barre ait fini de se charger.

@keyframes cat{
    0% {
        transform: translateX(-9999px);
    }
    100% {
        transform: translateX(0);
    }
}

La propriété  transform  avec sa fonction  translateX()  nous permet de déplacer notre chat hors de l'écran au début de l'animation, et mettre sa valeur de fin à 0, ce qui l'amène à son point de destination. Nous avons également déclaré la durée et le délai de lancement de l'animation dans des variables, ce qui nous permet de changer ces valeurs plus facilement (merci Sass 🔥).

Maintenant, ajoutons notre animation de chat à notre div  .cat. Nous ne voulons pas que notre chat bouge. Nous voulons simplement qu'il apparaisse quand la barre est complètement chargée. Nous réglons donc la durée de l'animation sur 0. Le délai, quant à lui, correspond à la combinaison entre la durée de l'animation progress-bar avec son délai de lancement :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay;
.cat {
    animation: cat 0ms $cat-delay;
}

@keyframes cat{
0% {
    transform: translateX(-9999px);
}
100% {
    transform: translateX(0);
    }
}

Et quand nous la vérifions dans le navigateur...

                                                  Image de chat

... le résultat est toujours le même. Notre chat cache toujours tout notre travail. Heureusement qu'il est mignon. Cette fois-ci, ajoutons une durée à notre animation pour voir pourquoi les choses ne se passent pas comme prévu :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay;
.cat {
    animation: cat 1000ms $cat-delay;
}
@keyframes cat{
0% {
    transform: translateX(-9999px);
}
100% {
    transform: translateX(0);
    }
}

Maintenant, notre chat va glisser en position en l'espace d'une seconde :

                         Animation avec translation de la photo de chat sur la barre de chargement

Eh bien, ce n'est pas exactement ce que nous attendions... Notre image apparaît au chargement de notre page, puis disparaît brusquement avant de se placer comme on s'y attendait. Pas tout à fait ce que nous voulions... 

Mais justement, ce comportement ne vous dit pas quelque chose ? 🤔

Quelque chose de très similaire se produit avec notre barre de progression, sauf qu'elle disparaît une fois l'animation terminée

En fait, lorsque notre animation n'est pas en train d'être animée, les éléments reviennent à leur valeur de propriété assignée. C'est pourquoi notre barre de progression disparaît à la fin de son animation ; elle anime l'échelle horizontale de 0 à 1, mais elle a une valeur  scaleX()  de 0 : 

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0);
        animation: progress-bar $prog-bar-dur $prog-bar-delay;
    }
}

Ainsi, lorsque l'animation se termine, la barre revient à sa valeur assignée pour  scaleX(), qui est aussi 0, disparaissant ainsi du site :

Animation de la barre de chargement seule

Il en va de même pour les éléments qui ont des animations avec des délais assignés. Pendant que l'élément attend de démarrer son animation, il utilisera les valeurs des propriétés qui lui ont été assignées. Pour tester cela par nous-même, réglons la valeur  scaleX()  de la barre  .progress__bar  sur .5 et augmentons le délai pour une valeur plus visible, par exemple 1000ms :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 1000ms;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
    animation: progress-bar $prog-bar-dur $prog-bar-delay;
    }
}

Ajoutons des commentaires à notre  div .cat  pour que nous puissions nous concentrer pour l'instant sur la barre de progression :

<html>
    <div class="container">
        <div class="progress">
            <div class="progress__bar"></div>
        </div>
        <!-- <div class="cat">
        <p>Merci pour votre patience</p>
        <p>Voici votre chat</p>
        </div> -->
    </div>
</html>

Voyons maintenant comment se comporte notre barre de progression :

Barre de progression rechargée à moitié

Notre barre de progression respecte un délai d'une seconde avant de s'animer. En attendant, elle est à une échelle de 50 % sur l'axe des X et 100 % d'opacité. Puis, tout à coup, elle passe à une scaleX() de 0, une opacité de .1 et commence à s'animer jusqu'à ce que la barre soit pleine et complètement opaque. Puis, une fois l'animation terminée, la barre revient à ses valeurs assignées dans le sélecteur.

Étendez les propriétés de vos keyframes avec animation-fill-mode

Pourtant, nous voulons que notre animation s'étende de la gauche vers la droite, en remplissant l'espace avant que l'animation ne commence puis se termine avec les valeurs de début et de fin de l'animation. Nous pouvons nous représenter notre animation par un dégradé de couleur, allant d'un vert menthe au bleu marine :

Image représentant le dégradé de couleurs

Plutôt que de commencer et de terminer la couleur au début du dégradé de couleur, nous voulons que la couleur de départ remplisse l'espace à gauche du dégradé, en reprenant la couleur de départ, puis que la couleur de fin s'étende vers la droite du dégradé, basée sur la couleur de fin :

Image représentant le dégradé complet

Pour remplir les espaces avant et après nos animations avec keyframes, nous pouvons utiliser la propriété animation-fill-mode, qui va étendre les valeurs de début d'une animation, ou ses valeurs finales, ou les deux.

animation-fill-mode  accepte trois mots clés différents comme valeur. Le premier est backwards (pour "en arrière"). Backwards étend les valeurs de départ d'une animation pour la période de temps qui précède le début de l'animation :

Image représentant le dégradé avec backwards

Comme backwards étend cette valeur au début, ce mot clé n'est utile que si nous avons un délai appliqué à nos animations. S'il n'y a pas de délai, il n'y a pas de vide à remplir avant l'animation pour  animation-fill-mode.

Ajoutons maintenant animation-fill-mode à la barre  .progress__bar  avec le mot clé backwards :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 1000ms;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay;
        animation-fill-mode: backwards;
    }
}

Maintenant, plutôt que de commencer à moitié remplie, notre barre de progression reste vide pendant toute la durée de son délai (animation-delay). À la fin du délai, l'animation continue normalement, et à la fin, revient en arrière à la valeur assignée de  scaleX(.5)  :

animation-fill-mode: backwards pour la barre de progression

Le deuxième mot clé pour le mode animation-fill-mode est forwards (pour "en avant"). Au contraire de backwards, forwards étend les valeurs finales d'une animation vers l'avant, sans fin :

Une image du dégradé avec forwards

Forwards consiste en quelque sorte à dire au navigateur de mettre l'animation sur pause sur la toute dernière image, plutôt que de passer aux valeurs assignées. Changeons la valeur de  animation-fill-mode  de la barre  .progress__bar  avec forwards et découvrons ce que ça donne :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 1000ms;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay;
        animation-fill-mode: forwards;
    }
}

Maintenant, notre barre de progression est de nouveau à 50 % jusqu'à ce que l'animation commence. Elle revient à 0 en animant à partir de là. Mais plutôt que de revenir directement à 50 %, la barre reste pleine :

animation-fill-mode forwards pour la barre de progression

Dans notre cas, il semble évident que nous voulons que notre animation s'étende et se remplisse, dans les deux sens, comme celle de notre barre de progression. Le mot clé judicieusement intitulé both (les deux) pour le mode animation-fill-mode remplit l'animation dans les deux sens :

Une image de dégradé avec both

Réglons le mode animation-fill-mode de la barre   .progress__bar  sur both :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 1000ms;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay;
        animation-fill-mode: both;
    }
}

Vérifions dans le navigateur. Nous devrions voir notre barre partie de 0 % de remplissage jusqu'à ce que l'animation commence, puis se remplir normalement, et ensuite rester à 100 % :

animation-fill-mode: both pour la barre de progression

Et voilààààààààààà une barre de progression fonctionnelle avec nos keyframes 🙌 ! Plutôt pas mal ! Réduisons le délai à nos 100 ms d'origine. D'ailleurs, tout comme avec nos autres propriétés d'animation, nous ne sommes pas obligés d'indiquer la propriété animation-fill-mode séparément. Au lieu de cela, nous pouvons définir sa valeur directement dans la propriété  animation  raccourcie : 

$prog-bar-dur: 1000ms;
$prog-bar-delay: 1000ms;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay both;
    }
}

Nous avons maintenant une barre de progression fonctionnelle.

Revenons maintenant à notre chat. Nous pouvons utiliser animation-fill-mode. Nous voulons que l'animation s'étende dans les deux sens, pour qu'elle reste invisible jusqu'à la fin du délai, puis reste visible après cela. Ajoutons donc le mot clé both à la propriété d'animation de  .cat   : 

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay both;
    }
}
.cat {
    animation: cat 0ms $cat-delay both;
}

J'espère que ça va marcher, que la barre de chargement s'affichera dès le chargement de la page. Qu'elle sera vide dans un premier temps, puis qu'elle se remplira pour enfin laisser apparaître l'image de chat :

                                             Barre de progression avec photo de chat

Yaaaaay ! On a réussi !

Maintenant que tout marche comme voulu, nous pouvons faire quelques petits ajustements.

Nous ne voyons presque pas la barre de progression complètement pleine, car notre image de chat se charge dès que la barre est pleine, ce qui nous laisse peu de temps pour enregistrer que le processus de chargement est terminé. Ajoutons un peu de retard entre la fin de l'animation de la barre de progression et le début de l'animation du chat. Nous pouvons multiplier la variable $prog-delay par 2 dans$cat-delay, ce qui nous donnera 150 ms supplémentaires avant le début de l'animation du chat :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay*2;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay both;
    }
}
.cat {
    animation: cat 0ms $cat-delay both;
}

Jetons à nouveau un coup d'œil au navigateur :

                                                  Barre de chargement avec un délai supplémentaire avant l'affichage de l'image de chat

Beaucoup plus joli. Ce n'est pas un changement énorme, mais ce petit délai supplémentaire entre les deux animations nous permet de comprendre que la barre a fini de se charger, ce qui aide à mieux anticiper et trouver plus fluide le passage direct au contenu du chat.

Animez varié et équilibré

Maintenant que nous avons chargé notre contenu comme nous le voulions, revenons plus spécifiquement à l'animation de la barre de progression et aux pauses et accélérations qu'elle crée lorsque la barre se remplit :

Barre de progression avec image de chat

Elles ajoutent un peu de texture à notre animation, mais elles sont assez uniformes. Pour l'instant, chaque keyframe a une accélération et un ralentissement par défaut, que nous pourrions aussi écrire en cubic-bezier (.25,.1,.25,1).

Ainsi, chaque keyframe dans la barre de progression se voit assigner ces valeurs cubic-bezier, comme si l'intervalle entre deux keyframes était sa propre animation, avec son propre « ease-in » et « ease-out ». Dans notre graphique cubic-bezier, cela ressemblerait à cela :

Le graphique cubic-bézier de l'animation

Nous voyons bien comment chaque keyframe a sa propre courbe d'accélération, dictée par la fonction animation-timing. Pour rendre cela un peu plus clair, assignons notre propre fonction de timing, plus extrême, à notre animation progress-bar. Utilisons beaucoup de « easing », ce qui va créer un contraste plus marquant d'un point de vue du rythme au cours de l'animation. Quelque chose comme cubic-bezier(.9,0,.1,1) :

Le cubic-bézier pour une animation plus marquée

Pour assigner notre courbe d'accélération  cubic-bezier()  à  progress-bar  , nous pouvons utiliser la propriété animation-timing-function, avec la fonction cubic-bezier comme valeur :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay*2;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay both;
        animation-timing-function: cubic-bezier(.9,0,.1,1);
    }
}

Nous pouvons également raccourcir les choses et ajouter la fonction cubic-bezier à notre propriété d'animation abrégée :

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay*2;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay both cubic-bezier(.9,0,.1,1);
    }
}

Maintenant, les ease-in et ease-out de nos keyframes sont beaucoup plus marqués. Notre animation paraît donc plus irrégulière. Lorsque nous regardons notre barre de progression à nouveau dans le navigateur, nous voyons des pauses beaucoup plus délibérées et des accélérations dans le mouvement de la barre :

Barre de progression chat avec animation cubic-bezier

Bien que les accélérations soient nettement plus visibles avec notre fonction cubic-bezier, elles sont probablement un peu exagérées. En général, la fonction de « ease timing » par défaut fonctionne assez bien. Le problème vient du keyframe à 24 %. Il est trop proche du keyframe précédent, qui, à 17 %, n'est séparé que de 7 %. La proximité des deux keyframes, combinée à l'uniformité des courbes d'accélération, entraîne une légère perte de la pause/accélération du deuxième keyframe.

Un keyframe hérite par défaut du timing défini dans le sélecteur où l'animation a été assignée, sauf si une fonction de timing a été explicitement assignée à ce keyframe. Pour assigner une fonction de timing à un keyframe spécifique, il suffit de déclarer la propriété animation-timing-function dans le keyframe en question. Revenons à notre fameux keyframe de  24 % : 

$prog-bar-dur: 1000ms;
$prog-bar-delay: 150ms;
$cat-delay: $prog-bar-dur + $prog-bar-delay*2;
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0.5);
        animation: progress-bar $prog-bar-dur $prog-bar-delay both;
    }
}
@keyframes progress-bar{
    0% {
        transform: scaleX(0);
        opacity: .1;
    }
    17% {
        transform: scaleX(.18);
    }
    24% {
        transform: scaleX(.40);
        animation-timing-function: cubic-bezier(.9,0,.1,1);
    }
    46% {
        transform: scaleX(.81);
    }
    85%,100% {
        opacity: 1;
    }
        100% {
        transform: scaleX(1);
}

Lorsque nous assignons une fonction de timing à un keyframe, nous contrôlons la courbe d'accélération des valeurs entre ce keyframe et le suivant. Cela signifie que nous contrôlons l'introduction lente du mouvement à 24 % et la sortie lente à 46 % :

La partie qui nous intéresse du cubic-bézier

Observons comment notre barre de progression s'affiche dans le navigateur avec sa nouvelle fonction de timing de keyframe :

Animation barre de progression image chat avec fonction de timing par keyframe

Maintenant, l'accélération du keyframe à 24 % est beaucoup plus prononcée, tandis que les autres restent à des valeurs d'introduction et de sortie plus fluides. Ce qui est presque parfait.... presque... mais, puisque nous y mettons tant d'efforts, autant le faire jusqu'au bout. 

Il y a un petit problème lors de l'accélération du keyframe 46 %. Ceci s'explique par le fait que la fonction de timing précédente, déclarée sur 24 %, a une fin longue et plane, tandis que le début de la fonction de timing du keyframe suivant de cubic-bezier (.25,.1,.25,1) est plus court avec une pente plus raide. Le mouvement paraît moins harmonieux :

Zoom sur la courbe cubic-bézier

Donnons également au keyframe 46 % sa propre fonction de timing et utilisons-la pour fluidifier un peu cette transition. Pour rendre le mouvement plus fluide, il suffit d'aplanir son début, pour mieux enchaîner avec la sortie du keyframe précédent. Pour l'instant, notre "ease in" a une coordonnée Y de .1. Si nous le réduisons à 0, nous obtenons un cubic-bezier(.25, 0, .25,1) et un "ease in" plus plat :

La courbe plus

Intégrons notre nouvelle fonction de timing au keyframe 46 %.

Par ailleurs, l'animation de l'opacité ne semble plus vraiment ajouter de valeur. Au contraire, elle rend notre animation moins visible. Supprimons-la et simplifions un peu les choses :

@keyframes progress-bar{
    0% {
        transform: scaleX(0);
    }
    17% {
        transform: scaleX(.18);
    }
    24% {
        transform: scaleX(.40);
        animation-timing-function: cubic-bezier(.9,0,.1,1);
    }
    46% {
        transform: scaleX(.81);
        animation-timing-function: cubic-bezier(.25,0.25,1);
    }
    100% {
        transform: scaleX(1);
    }
}

Voyons ce que ça donne :

                                                            Animation barre de progression fonction de timing personnalisée et pas de changement d'opacité

Beaucoup mieux. 

Bravo ! Nous avons une barre de progression avec un ressenti plus authentique grâce à l'utilisation des @keyframes, et de la propriété animation-timing-function. Les propriétés animation-delay et animation-fill-mode nous permettent également d'enchaîner les animations entre elles au mieux.

Encore une fois, si vous souhaitez vous amuser avec le code, je vous mets un CodePen à disposition.

Pourquoi ne pas essayer de changer la durée de la propriété animation-timing-function ?

Résumé

  • les animations CSS @keyframes peuvent être déclenchées en utilisant des pseudoclasses telles que  :hover, tout comme les transitions ;

  • les @keyframes CSS peuvent également être déclenchés par le chargement des éléments auxquels ils sont assignés, comme un sélecteur. Par exemple, dès le chargement d'une page ; 

  • nous pouvons retarder le démarrage des animations avec keyframes en utilisant la propriété  animation-delay, avec un délai exprimé en secondes ou en millisecondes, tout comme les transitions ;

  • nous pouvons étendre ces valeurs du début à la fin de ces animations en utilisant la propriété  animation-fill-mode :

    • le mot clé « backwards » prolonge les valeurs de départ d'une animation avant son lancement, couvrant la durée du délai assigné avant que l'animation elle-même ne commence,

    • le mot clé « forwards » prolonge les valeurs finales d'une animation jusqu'à ce que la page soit rechargée ou que le navigateur soit fermé,

    • le mot clé « both » prolonge l'animation dans les deux sens ;

  • nous pouvons définir une fonction de timing des @keyframes en utilisant la fonction animation-timing-function sur le sélecteur où l'animation a été assignée ;

  • nous pouvons également définir un timing spécifique keyframe par keyframe, en assignant la propriété  animation-timing-function  aux keyframes en question.

Au chapitre suivant, nous verrons de nouvelles propriétés liées aux @keyframes. Nous verrons notamment comment écrire des animations plus concises et réutilisables, mais nous apprendrons également à mettre nos animations sur pause. À très vite ! 🚀

Exemple de certificat de réussite
Exemple de certificat de réussite