Créez une animation de chargement avec CSS3

| Johnny Simpson | Didier Mouronval (traducteur) |

Traducteur

Bovino

Voici une petite réalisation que j'ai faite sur mon temps libre, juste pour le fun. Cela m'a pris beaucoup de temps lorsque j'ai réalisé que le moyen le plus simple pour y parvenir était de placer chaque barre et de la faire pivoter dans la bonne position. En particulier, modifier la position par pas de 2 % a été atroce. J'ai choisi d'utiliser les pourcentages afin de rendre l'ensemble redimensionnable facilement et cela peut l'être, car modifier les dimensions manuellement est surement la chose la plus aliénante que vous pouvez faire !

Cet article est la traduction de Making a Loading Icon in just CSS!, publié sur le blog inserthtml.

Commentez

- Titre : Créez une animation de chargement avec CSS3

- Auteurs : Johnny Simpson, Didier Mouronval (traducteur)

- Traducteur : Bovino

- Parution : 23 mai 2012

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2012 Johnny Simpson. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- Présentation

- Fonctionnement

- Conclusion et remerciements

Présentation

Voir une démo en ligne

Voir une démo en ligne.

Téléchargez l'archive de l'exemple.

Cet exemple fonctionne avec :

Webkit

Mozilla

Trident

Presto

Oui

Oui

Oui

Pas d'animation

Fonctionnement

De façon basique, j'ai utilisé un ensemble de balises <div> et les ai mises dans un conteneur global. Chaque div interne ayant une taille définie selon un pourcentage du conteneur et animé de façon à en changer l'opacité. Cela semble facile non ? En tout cas, cela l'aurait été si changer la position d'un élément avait été plus simple et si une propriété comme animation existait dans les navigateurs, ou si au moins, en la définissant, le navigateur était capable d'ajouter son propre préfixe automatiquement, ce qui aurait évité d'utiliser -moz-, -webkit- et -ms-.

L'une de mes pires déceptions en créant cette animation a été de me rendre compte qu'elle ne fonctionnerait pas avec Opera. J'ai pourtant tout essayé, mais comme il ne supporte pas les animations, cela ressemblera plus à une roue bizarre qu'à une animation de chargement avec ce navigateur.
Mais passons au code. Voici à quoi ressemble la structure HTML :

<div class="spinner">
<div class="piece a"> </div>
<div class="piece b"> </div>
<div class="piece c"> </div>
<div class="piece d"> </div>
<div class="piece e"> </div>
<div class="piece f"> </div>
<div class="piece g"> </div>
<div class="piece h"> </div>
<div class="piece i"> </div>
<div class="piece j"> </div>
<div class="piece k"> </div>
<div class="piece l"> </div>
<div class="piece m"> </div>
<div class="piece n"> </div>
<div class="piece o"> </div>
<div class="piece p"> </div>
</div>

Quant au CSS, le voici :

.spinner {
width: 32px;
height: 32px;
}

.piece {
background: #000;
width: 50%;
height: 14%;
position: relative;
}

.spinner div {
opacity: 0.2;
}

@-webkit-keyframes fade {

5% { opacity: 0.8; }
30% { opacity: 0.5; }

}
@-ms-keyframes fade {

5% { opacity: 0.8; }
30% { opacity: 0.5; }

}
@-moz-keyframes fade {

5% { opacity: 0.8; }
30% { opacity: 0.5; }

}

.a, .p {
height: 50%;
width: 14%;
left: 99%;
}

.a {
top: 5%;
-webkit-animation: fade 3.2s ease-in infinite;
-moz-animation: fade 3.2s ease-in infinite;
-ms-animation: fade 3.2s ease-in infinite;
}

.b {
bottom: 21%;
left: 50%;
-webkit-animation: fade 3.2s ease-in-out 3s infinite;
-moz-animation: fade 3.2s ease-in-out 3s infinite;
-ms-animation: fade 3.2s ease-in-out 3s infinite;
}

.c {
bottom: 34%;
left: 110%;
-webkit-animation: fade 3.2s ease-in-out 0.2s infinite;
-moz-animation: fade 3.2s ease-in-out 0.2s infinite;
-ms-animation: fade 3.2s ease-in-out 0.2s infinite;
}

.d {
bottom: 31%;
left: 27%;
-webkit-animation: fade 3.2s ease-in-out 2.8s infinite;
-moz-animation: fade 3.2s ease-in-out 2.8s infinite;
-ms-animation: fade 3.2s ease-in-out 2.8s infinite;
}

.e {
bottom: 43%;
left: 134%;
-webkit-animation: fade 3.2s ease-in-out 0.4s infinite;
-moz-animation: fade 3.2s ease-in-out 0.4s infinite;
-ms-animation: fade 3.2s ease-in-out 0.4s infinite;
}

.f {
bottom: 32%;
left: 11%;
-webkit-animation: fade 3.2s ease-in-out 2.6s infinite;
-moz-animation: fade 3.2s ease-in-out 2.6s infinite;
-ms-animation: fade 3.2s ease-in-out 2.6s infinite;
}

.g {
bottom: 45%;
left: 149%;
-webkit-animation: fade 3.2s ease-in-out 0.6s infinite;
-moz-animation: fade 3.2s ease-in-out 0.6s infinite;
-ms-animation: fade 3.2s ease-in-out 0.6s infinite;
}

.h {
bottom: 30%;
left: 6%;
-webkit-animation: fade 3.2s ease-in-out 2.4s infinite;
-moz-animation: fade 3.2s ease-in-out 2.4s infinite;
-ms-animation: fade 3.2s ease-in-out 2.4s infinite;
}

.i {
bottom: 43%;
left: 155%;
-webkit-animation: fade 3.2s ease-in-out 0.8s infinite;
-moz-animation: fade 3.2s ease-in-out 0.8s infinite;
-ms-animation: fade 3.2s ease-in-out 0.8s infinite;
}
.j {
bottom: 29%;
left: 12%;
-webkit-animation: fade 3.2s ease-in-out 2.2s infinite;
-moz-animation: fade 3.2s ease-in-out 2.2s infinite;
-ms-animation: fade 3.2s ease-in-out 2.2s infinite;
}

.k {
left: 149%;
bottom: 41%;
-webkit-animation: fade 3.2s ease-in-out 1s infinite;
-moz-animation: fade 3.2s ease-in-out 1s infinite;
-ms-animation: fade 3.2s ease-in-out 1s infinite;
}

.l {
bottom: 30%;
left: 28%;
-webkit-animation: fade 3.2s ease-in-out 2s infinite;
-moz-animation: fade 3.2s ease-in-out 2s infinite;
-ms-animation: fade 3.2s ease-in-out 2s infinite;
}

.m {
bottom: 43%;
left: 134%;
-webkit-animation: fade 3.2s ease-in-out 1.2s infinite;
-moz-animation: fade 3.2s ease-in-out 1.2s infinite;
-ms-animation: fade 3.2s ease-in-out 1.2s infinite;
}

.n {
bottom: 40%;
left: 50%;
-webkit-animation: fade 3.2s ease-in-out 1.8s infinite;
-moz-animation: fade 3.2s ease-in-out 1.8s infinite;
-ms-animation: fade 3.2s ease-in-out 1.8s infinite;
}

.o {
left: 110%;
bottom: 52%;
-webkit-animation: fade 3.2s ease-in-out 1.4s infinite;
-moz-animation: fade 3.2s ease-in-out 1.4s infinite;
-ms-animation: fade 3.2s ease-in-out 1.4s infinite;
}
.p {
bottom: 78%;
-webkit-animation: fade 3.2s ease-in-out 1.6s infinite;
-moz-animation: fade 3.2s ease-in-out 1.6s infinite;
-ms-animation: fade 3.2s ease-in-out 1.6s infinite;
}

.b, .o {
-webkit-transform: rotate(67.5deg);
-moz-transform: rotate(67.5deg);
-ms-transform: rotate(67.5deg);
-o-transform: rotate(67.5deg);
}

.d, .m {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
}

.f, .k {
-webkit-transform: rotate(22.5deg);
-moz-transform: rotate(22.5deg);
-ms-transform: rotate(22.5deg);
-o-transform: rotate(22.5deg);

}

.n, .c {
-webkit-transform: rotate(-67.5deg);
-moz-transform: rotate(-67.5deg);
-ms-transform: rotate(-67.5deg);
-o-transform: rotate(-67.5deg);}

.l, .e {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
}

.j, .g {
-webkit-transform: rotate(-22.5deg);
-moz-transform: rotate(-22.5deg);
-ms-transform: rotate(-22.5deg);
-o-transform: rotate(-22.5deg);
}

Je pourrais passer du temps à expliquer tout cela, mais de façon simple, j'ai juste fait pivoter mon paquet de div et utilisé des transformations pour les faire ressembler à une roue. Puis j'ai ajouté quelques animations simples pour faire un fondu sur chaque rayon au bon moment, j'ai enfin appliqué ces animations avec des retards adaptés pour que le rendu soit correct. Si vous voulez plus de détails sur les animations, vous pouvez lire mon article à ce sujet.

Puisque j'ai utilisé des valeurs en pourcentage (mon coup de génie), vous pouvez changer les dimensions de la classe .spinner et l'ensemble sera impacté. Mais rappelez-vous que la taille indiquée ne correspond pas à la taille de l'animation, elle sera plus grande. Notez au passage que le CSS compressé fait environ 4 ko, ce qui est moins que la plupart des fichiers gif que l'on trouve habituellement. Bien sûr, ce n'est peut-être pas encore une solution idéale, puisqu'elle n'est pas supportée à 100 %, mais espérons que ça le sera un jour.

Voir une démo en ligne.

Téléchargez l'archive de l'exemple.

Conclusion et remerciements

C'est terminé. Si cet article vous a plu, n'hésitez pas à le commenter et à proposer vos idées d'améliorations. (NDT Y compris sur le site de l'article original.)

Cet article a été publié avec l'aimable autorisation de Johnny Simpson. L'article original peut être lu sur le site de inserthtml : Making a Loading Icon in just CSS!.

Nous tenons aussi à remercier ClaudeLELOUP pour sa relecture attentive de cet article.