Techno-magis

  • Home
  • July 2014
  • Petite animation de chargement avec “CSS animation”, “CSS transform” et les variables CSS

Petite animation de chargement avec “CSS animation”, “CSS transform” et les variables CSS

Saturday 12th July 2014

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 :

CODE:

 
/* 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 :

CODE:

<div class="loading">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

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 :

CODE:

 
: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) );
}
 

Categories:
By Zéfling, the 12/07/2014 at 22:50:00
The ticket was read 387 times, with 2 comments posted.

2 comments posted

By Tarh, the 13/12/2014 at 11:11:11
Guest

Intéressant.
Mais ça pompe plus de CPU qu'un GIF animé.

By Zéfling, the 18/12/2014 at 08:03:54
Avatar
Administrator

Je te dirais que ça offre plus de possibilités de customisation qu'un GIF qui sera en 256 couleurs avec un seul niveau de transparence et même d'un APNG (mais lui n'est supporté que par Firefox et Safari). Toutefois, l'idée est de montrer que l'on peut faire des choses uniquement avec du CSS. 😉

La plus grande consolation de la médiocrité, c'est que le génie n'est pas immortel.

Write a commentary