Le 6 août 2024, Basti Ui, l’incroyable youtubeur UX/UI, publie un tweet en questionnant les quoicou-développeurs :
Le challenge est le suivant arriver à créer une animation CSS d’incrémentation comme de nombreux sites pour suivre des évolutions. Example : Compteur d’abonné Youtube
Les points importants
Pour ce challenge, il va falloir faire attention à plusieurs points :
- Pas de Javascript (Basti Ui ne connais pas le Javascript et veut pouvoir comprendre le code)
- Un code simple (Tous pareil qu’au dessus, Basti Ui connais CSS et HTML mais n’est pas un développeur)
- L’animation doit commencer au chargement de la page
- Le nombre affiché doit pouvoir être facilement changeable dans le code (le nombre sera changé grâce à une API / valeur géré par un service tiers)
Première étape : comprendre la structure actuelle
La structure actuelle est simple, c’est une page HTML et un peu de CSS. La partie HTML qui nous intéresse est la <div>
avec la classe percentage
. Elle posède le nombre à incrémenter dans une balise <span>
et le caractère %
<div class="percentage"><span>18</span>%</div>
Au niveau du CSS, il y a uniquement des transformations au niveau du texte
.percentage {
font-size: 80px;
font-weight: bold;
color: #000;
}
La structre n’est pas compliqué et permettra de modifier ou ajouter le CSS et HTML sans casser quoi que ce soit
Le résultat
Voici le code que j’ai réalisé. Il comporte plusieurs parties importantes que je vais détailler plus bas.
HTML
<div class="percentage"><span><span id="tens" data-value="18"><span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span></span><span id="units" data-value="18"><span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span></span></span>%</div>
Le code est illisible comme ça mais c’est important de mettre les <span>
côte à côte, sinon il y aura des espaces non désirés entre les différents caractères. Voici une version du code plus lisible (attention elle donnera des espaces autour des chiffres)
<div class="percentage">
<span>
<span id="tens" data-value="18">
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
</span>
<span id="units" data-value="18">
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
</span>
</span>
%
</div>
CSS
Ensuite, voici le CSS qui place les éléments comme sur la version originale mais en prennant en compte la nouvelle structure HTML
#units,
#tens {
display: inline-flex;
flex-direction: column;
overflow: hidden;
line-height: 1;
height: 1em;
}
#units[data-value$="1"] > *,
#tens[data-value^="1"] > * {
animation: slide1 1.5s forwards;
}
#units[data-value$="2"] > *,
#tens[data-value^="2"] > * {
animation: slide2 1.5s forwards;
}
/* pareil 9 fois */
#units[data-value$="9"] > *,
#tens[data-value^="9"] > * {
animation: slide8 1.5s forwards;
}
@keyframes slide1 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
@keyframes slide2 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-200%);
}
}
/* pareil 9 fois */
@keyframes slide9 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-900%);
}
}
L’attribut data-value
L’attribut data-value
permet de transmettre des données du HTML vers le CSS. Il est aussi possible d’utiliser une classe, le code HTML aurai été <span id="tens" class="value-18">
.
En utilisant l’attribut data-value
on rend la variable dynamic. Il suffit de changer la valeur de data-value
et l’animation s’adapte au nouveau nombre.
Dans le CSS, on selectionne la bonne animation grâce au selecteur suivant.
#units[data-value$="1"] > *,
#tens[data-value^="1"] > * {
animation: slide1 1.5s forwards;
}
On remarque que le selecteur est différent entre les décimals et les unités. Le $
dans [data-value$="1"]
sélectionne les data-value
qui commence par 1
et avec *
c’est les data-value
qui finissent par 1
Préparation pour l’animation
Dans le HTML, chaque chiffre est présent. Cela permet de pouvoir les voir lorsque l’animation se joue.
Ensuite, le CSS met en colonne les chiffres des unités grâce à display: flex;
mais sans changer la taille ou les styles adjacent. Cela fonctionne en bloquant la hauteur de #units
et #tens
(line-height: 1;
et height: 1em;
)
Enfin, on remonte les chiffre de x fois la taille afin d’afficher le chiffre x. Si on remonte les éléments de 800%, le chiffre 8 sera visible (transform: translateY(-900%);
)
L’animation
Pour animer, il suffit d’ajouter une animation CSS qui fera défiler les chiffres.
#units > * {
animation: slide 1.5s forwards;}
@keyframes slide {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-600%);
}
}
L’animation ce joue dès que la page est chargé. Le chiffre affiché à la fin de l’animaiton reste visible grâce à la propriété forwards
.
Conclusion
En définisant les attentes et en décomposant le projet en plusieurs étapes clées, on peut arriver à faire des choses qui paraissent complexe au premier abord. Ce projet peut paraître compliqué en apparence (rendre dynamic du CSS) mais en décomposant en petites étapes on arrive à résoudre le problème sans Javascript.
Vous pouvez voir le résulat ici : https://bazar.hugolevet.fr/basti-quoicoudev-number/