Je me disais que j'allais voir s'il était possible de faire facilement une petite animation de chargement rien qu'avec du CSS et des bêtes éléments HTML. Vous savez, le truc avec des barres rectangulaires qui donnent l'impression que ça tourne. Quitte à faire ça bien, que ça soit en plus paramétrable, maintenant qu'il est possible d'utiliser les variables CSS.
Pour l'instant, mon but est avant tout d'amuser avec Firefox OS 2.0 et WebIDE actuellement fourni dans Nightly, la version de développent de Firefox.
J'avais pensais que ça serait cool de pouvoir faire ça rien qu'avec du CSS et ça l'est, à un détail près, il faut faire tous les éléments un à un. Mon côté développeur déteste cela.
Tout ceci est animé uniquement exclusivement avec du CSS :
/* les variables pour une modification plus simple */
:root {
--loadingAnimStart: rgba(0,0,0,0);
--loadingAnimEnd : rgba(0,0,0,255);
}
/* la définition de l’animation, très simple pour la variation de couleur du rectangle */
@keyframes loadingAnim{
from {
background-color:rgba(0,0,0,0);
background-color:var(--loadingAnimStart);
}
to {
background-color:rgba(0,0,0,255);
background-color:var(--loadingAnimEnd);
}
}
.loading {
display: block;
width: 5px;
margin: auto;
height: 60px;
}
/* la définition commune à toutes les rectangles */
.loading > span {
display: block;
width: 5px;
height: 20px;
/* pour que l'animation semble cohérente, il vaut mieux utiliser la couleur de démarrage */
background-color: rgba(0,0,0,0);
background-color: var(--loadingAnimStart);
position: absolute;
transform-origin: 50% 150%;
animation: 1.12s linear 0s normal none infinite loadingAnim;
}
/* les changements individuels */
.loading > span:nth-child(2) {
transform: rotate(30deg); /* le temps est 1/12e de 360° */
animation-delay:.1s; /* le temps est 1/12e de la durée total */
}
.loading > span:nth-child(3) {
transform: rotate(60deg);
animation-delay:.2s;
}
.loading > span:nth-child(4) {
transform: rotate(90deg);
animation-delay:.3s;
}
.loading > span:nth-child(5) {
transform: rotate(120deg);
animation-delay:.4s;
}
.loading > span:nth-child(6) {
transform: rotate(150deg);
animation-delay:.5s;
}
.loading > span:nth-child(7) {
transform: rotate(180deg);
animation-delay:.6s;
}
.loading > span:nth-child(8) {
transform: rotate(210deg);
animation-delay:.7s;
}
.loading > span:nth-child(9) {
transform: rotate(240deg);
animation-delay:.8s;
}
.loading > span:nth-child(10) {
transform: rotate(270deg);
animation-delay:.9s;
}
.loading > span:nth-child(11) {
transform: rotate(300deg);
animation-delay:1s;
}
.loading > span:nth-child(12) {
transform: rotate(330deg);
animation-delay:1.1s;
}
Et pour le HTML, un conteneur et les 12 rectangles à animer :
Voilà qui aurait été plus simple pour les 12 éléments, mais de fait beaucoup plus complexe à lire.
- Le nth-child ne permet pas t'attribuer une plage, ce qui aurait était intéressant si un 13 éléments étaient utilisés pour autre chose, comme écrire « chargement en court » sans recourir à un nouveau parent. Pour chaque nouvel élément il faudra créer une exception :not().
- Il n'est pas possible utiliser la position d'un élément, il est possible de cibler un nth-child, impossible de s'en servir dans une calc()
- Et tout de façon, aujourd'hui il n'est pas possible de faire un calc() avec une variable CSS.
Voilà une proposition :
:root {
--loadingAnimTime : 1.12s;
--loadingAnimCount: 12;
}
/* ceci est totalement invalide */
.loading > span:nth-child(n in (1 to var(--loadingAnimCount))) {
transform: rotate(calc( ( 360deg / var(--loadingAnimCount) ) * ( nth-child-index - 1 ) ));
animation-delay: calc( ( var(--loadingAnimTime) / var(--loadingAnimCount) ) * ( nth-child-index - 1) );
}