Bouncing Dots
Trois cercles de 12 px en ligne qui s'effacent et réapparaissent en cascade — scale(0) → scale(1) en 0,56 s, délais négatifs de 0,16 s entre chaque point, pure CSS, zéro JavaScript.
Cet effet est gratuit — la catégorie Chargement en contient 29 au total, dont 4 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →
Exemples d'usage
Recherche d'un chauffeur à proximité…
3 chauffeurs sollicités · réponse en général sous 2 min
Génération de votre clip…
Durée variable — en général moins d'une minute.
Comment ça marche
Trois <span> vides sont posés dans un conteneur display: flex, gap: 8 px. Chaque cercle mesure 12 × 12 px (border-radius: 50 %, fond #6366f1), pour un encombrement total mesuré de 52 × 12 px. La règle commune .loader-dots span leur applique l'animation dotBounce : 1,4 s, ease-in-out, infinie. Pas de JavaScript — l'effet est entièrement déclaratif.
La keyframe dotBounce fait passer chaque cercle de scale(0) aux positions 0 %, 80 % et 100 % à scale(1) à 40 %. Pic atteint à 0,56 s (40 % × 1,4 s), retour à zéro avant 1,12 s (80 %). De 1,12 s à 1,4 s les trois cercles sont simultanément invisibles — ce creux de 0,28 s par cycle constitue le blanc rythmique entre deux vagues. Il s'agit d'un pulsing d'échelle : les points ne se déplacent pas, ils disparaissent et réapparaissent sur place.
La cascade repose sur des délais négatifs : −0,32 s pour le premier cercle, −0,16 s pour le deuxième, aucun délai pour le troisième. Un délai négatif place le point directement à mi-cycle au chargement de la page — la vague est visible immédiatement, sans blanc initial. Résultat mesuré : le premier cercle atteint son pic à t = 0,24 s, le deuxième à t = 0,40 s, le troisième à t = 0,56 s. L'intervalle de 0,16 s est régulier et produit l'ondulation gauche → droite.
Accessibilité
- prefers-reduced-motion absent : aucune règle
@media (prefers-reduced-motion: reduce)dans le CSS livré. L'animation boucle indéfiniment quelle que soit la préférence système — non conforme WCAG 2.3.3. À ajouter :@media (prefers-reduced-motion: reduce) { .loader-dots span { animation: none; opacity: 1; } }pour figer les cercles à leur état visible. - Aucun marqueur sémantique : ni
role="status", niaria-label, niaria-livesur le conteneur. Les lecteurs d'écran ignorent ces cercles animés. Pour un indicateur de chargement, ajoutezrole="status"etaria-label="Chargement en cours"sur ladiv.loader-dots; pour un bouton en attente, préférezaria-busy="true"sur le bouton parent. - Texte alternatif absent : les trois
<span>sont vides. Si le loader est le seul signal visuel de traitement, ajoutez un nœud masqué visuellement mais lisible par lecteur d'écran :<span class="sr-only">Chargement…</span>(techniqueclip: rect(0,0,0,0)usuelle). - animation-play-state codé en dur à
running: la valeur est inscrite dans le raccourcianimationde chaquespan. Cibler.loader-dots { animation-play-state: paused }n'a aucun effet. Pour stopper via JavaScript (respect de prefers-reduced-motion ou masquage du loader), ciblez explicitement.loader-dots span { animation-play-state: paused }.
Compatibilité navigateur
Requiert CSS Animations, transform et gap pour flexbox. Zéro dépendance, zéro JavaScript.
Sur Chrome 43–83, Firefox 16–62 et Safari 9–14 : l'animation est active mais gap n'est pas supporté en contexte flex — les trois cercles sont collés sans espacement. Sur les navigateurs antérieurs sans CSS Animations, les cercles s'affichent à taille pleine, statiques.
Le code
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="loader-dots">
<span>
</span>
<span>
</span>
<span>
</span>
</div>
.loader-dots {
display: flex;
gap: 8px;
}
.loader-dots span {
width: 12px;
height: 12px;
background: rgb(99, 102, 241);
border-radius: 50%;
animation: 1.4s ease-in-out 0s infinite normal none running dotBounce;
}
.loader-dots span:nth-child(1) {
animation-delay: -0.32s;
}
.loader-dots span:nth-child(2) {
animation-delay: -0.16s;
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: scale(0);
}
40% {
transform: scale(1);
}
}
// Effet CSS pur — pas de JavaScript nécessaire
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Taille des cercles (CSS — .loader-dots span width/height) |
12 px | Encombrement total = 3 × taille + 2 × gap. À 8 px le loader s'insère dans un bouton standard ; à 16 px il s'affiche en composant autonome. |
Espacement (CSS — .loader-dots gap) |
8 px | Espace entre les boîtes de 12 px. Puisque les cercles collapsent jusqu'à un point en bas de cycle, le blanc visuel minimum entre eux est toujours gap + (taille × (1 − scale_min)). |
Couleur (CSS — .loader-dots span background) |
#6366f1 | Une seule propriété à changer. Vérifiez le contraste à scale(1) : WCAG 1.4.11 requiert 3:1 entre la couleur du cercle et le fond. |
Durée du cycle (CSS — animation-duration dans .loader-dots span) |
1,4 s | Les trois cercles gardent leurs rapports de délais automatiquement. 1,0 s = rythme alerte ; 2,0 s = rythme calme. L'intervalle entre les pics reste proportionnel : 0,16 s / 1,4 s ≈ 11,4 % du cycle. |
Décalage de la cascade (CSS — animation-delay sur les :nth-child) |
−0,32 s, −0,16 s, 0 s | L'écart de 0,16 s entre chaque cercle produit l'ondulation. Pour une vague plus marquée : −0,4 s / −0,2 s / 0 s. Gardez les délais négatifs pour que la cascade soit active dès le chargement. |
Fonction de timing (CSS — animation-timing-function) |
ease-in-out | ease-out fait apparaître les cercles rapidement et disparaître lentement ; linear donne un rythme mécanique. ease-in-out (défaut) adoucit les deux extrémités. |
Nombre de cercles (HTML — <span> supplémentaires + CSS) |
3 | Ajoutez un 4e <span> et une règle .loader-dots span:nth-child(4) { animation-delay: 0.16s; }. Le 4e cercle peake 0,16 s après le 3e. Le conteneur passe à 68 px (4 × 12 + 3 × 8). |
FAQ
L'animation est un pulsing d'échelle, pas un rebond vertical — comment la différencier de Bouncing Squares (fx-0433) ?
Bouncing Squares applique translateY(−20 px) : les carrés montent physiquement et retombent. Bouncing Dots applique scale(0) → scale(1) : les cercles disparaissent et réapparaissent sur place, sans déplacement. Le cas d'usage de prédilection de Dots est l'indicateur de saisie de type messagerie ; Squares évoque plutôt une progression avec rebond, plus « joueur ». Les deux sont en cascade mais leurs easing et leurs durées diffèrent (1,4 s ease-in-out contre 1,0 s ease-in-out).
Comment ajouter un quatrième cercle sans modifier les délais existants ?
Ajoutez un <span> après les trois existants et une seule règle : .loader-dots span:nth-child(4) { animation-delay: 0.16s; }. Le 4e cercle peake 0,16 s après le 3e (soit à t ≈ 0,72 s). Les règles nth-child(1) et nth-child(2) ne bougent pas. L'encombrement total passe à 68 px.
Pourquoi utiliser des délais négatifs plutôt que positifs (0 s, 0,16 s, 0,32 s) ?
Des délais positifs créent un blanc visible au chargement de la page : le 3e cercle attend 0,32 s avant d'apparaître pour la première fois. Avec des délais négatifs, chaque cercle est déjà à mi-course quand la page s'affiche — la cascade est immédiatement active. Wave Bars (fx-0426) applique le même principe sur ses cinq barres avec des délais négatifs de −1,2 s à −0,8 s.