Présentation▲
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:
32
px;
height:
32
px;
}
.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.2
s ease-in
infinite
;
-moz-animation:
fade 3.2
s ease-in
infinite
;
-ms-animation:
fade 3.2
s ease-in
infinite
;
}
.b
{
bottom
:
21
%;
left
:
50
%;
-webkit-animation:
fade 3.2
s ease-in-out
3
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
3
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
3
s infinite
;
}
.c
{
bottom
:
34
%;
left
:
110
%;
-webkit-animation:
fade 3.2
s ease-in-out
0.2
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
0.2
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
0.2
s infinite
;
}
.d
{
bottom
:
31
%;
left
:
27
%;
-webkit-animation:
fade 3.2
s ease-in-out
2.8
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
2.8
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
2.8
s infinite
;
}
.e
{
bottom
:
43
%;
left
:
134
%;
-webkit-animation:
fade 3.2
s ease-in-out
0.4
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
0.4
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
0.4
s infinite
;
}
.f
{
bottom
:
32
%;
left
:
11
%;
-webkit-animation:
fade 3.2
s ease-in-out
2.6
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
2.6
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
2.6
s infinite
;
}
.g
{
bottom
:
45
%;
left
:
149
%;
-webkit-animation:
fade 3.2
s ease-in-out
0.6
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
0.6
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
0.6
s infinite
;
}
.h
{
bottom
:
30
%;
left
:
6
%;
-webkit-animation:
fade 3.2
s ease-in-out
2.4
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
2.4
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
2.4
s infinite
;
}
.i
{
bottom
:
43
%;
left
:
155
%;
-webkit-animation:
fade 3.2
s ease-in-out
0.8
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
0.8
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
0.8
s infinite
;
}
.j
{
bottom
:
29
%;
left
:
12
%;
-webkit-animation:
fade 3.2
s ease-in-out
2.2
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
2.2
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
2.2
s infinite
;
}
.k
{
left
:
149
%;
bottom
:
41
%;
-webkit-animation:
fade 3.2
s ease-in-out
1
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
1
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
1
s infinite
;
}
.l
{
bottom
:
30
%;
left
:
28
%;
-webkit-animation:
fade 3.2
s ease-in-out
2
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
2
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
2
s infinite
;
}
.m
{
bottom
:
43
%;
left
:
134
%;
-webkit-animation:
fade 3.2
s ease-in-out
1.2
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
1.2
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
1.2
s infinite
;
}
.n
{
bottom
:
40
%;
left
:
50
%;
-webkit-animation:
fade 3.2
s ease-in-out
1.8
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
1.8
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
1.8
s infinite
;
}
.o
{
left
:
110
%;
bottom
:
52
%;
-webkit-animation:
fade 3.2
s ease-in-out
1.4
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
1.4
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
1.4
s infinite
;
}
.p
{
bottom
:
78
%;
-webkit-animation:
fade 3.2
s ease-in-out
1.6
s infinite
;
-moz-animation:
fade 3.2
s ease-in-out
1.6
s infinite
;
-ms-animation:
fade 3.2
s ease-in-out
1.6
s infinite
;
}
.b
,
.o
{
-webkit-transform:
rotate
(
67.5
deg);
-moz-transform:
rotate
(
67.5
deg);
-ms-transform:
rotate
(
67.5
deg);
-o-transform:
rotate
(
67.5
deg);
}
.d
,
.m
{
-webkit-transform:
rotate
(
45
deg);
-moz-transform:
rotate
(
45
deg);
-ms-transform:
rotate
(
45
deg);
-o-transform:
rotate
(
45
deg);
}
.f
,
.k
{
-webkit-transform:
rotate
(
22.5
deg);
-moz-transform:
rotate
(
22.5
deg);
-ms-transform:
rotate
(
22.5
deg);
-o-transform:
rotate
(
22.5
deg);
}
.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.
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.