ChargementGratuit

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.

CSSPlayful
Survolez ou cliquez la scène pour interagir

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

Léa Martinen ligne
Tu as pu regarder les maquettes de la page d'accueil ?
Oui, je les ai ouvertes ce matin.
Le hero plein écran est très réussi.
14:32
Léa est en train d'écrire…
Écrire un message…

① Indicateur de saisie dans une bulle de messagerie

QuandInterface de chat ou assistant conversationnel : l'interlocuteur ou le modèle IA formule sa réponse.
PourquoiTrois cercles en cascade sont le signal universel du « … » de saisie — reconnu sans libellé dans tous les usages de messagerie. Le format compact (52 × 12 px) s'insère dans une bulle sans la déformer.
RéglagesPoints 8 px, gap 5 px, couleur #ffffff sur fond de bulle coloré, durée 1,2 s.
Cabmo Confort · 4 places

Recherche d'un chauffeur à proximité…

3 chauffeurs sollicités · réponse en général sous 2 min

12 rue des Lilas Gare Saint-Lazare
14,50 € Annuler

② Recherche d'un chauffeur dans une application de VTC

QuandApplication de commande de course : la demande est partie, les chauffeurs à proximité sont sollicités et l'un d'eux doit accepter. L'attente dépend d'une décision humaine, pas d'un calcul.
PourquoiTrois points en cascade, c'est le « … » de la messagerie : quelqu'un est là et va répondre. C'est exactement ce que l'écran doit dire — on attend qu'un chauffeur accepte, pas qu'un traitement se termine. Un anneau tournant dirait « le système calcule », une barre promettrait une durée que personne ne connaît. Le creux de 0,28 s entre deux vagues donne le rythme d'un interlocuteur qui compose sa réponse. Posés en 16 px au centre du panneau, les trois points se lisent sur un téléphone tenu à bout de bras.
RéglagesPoints 16 px, gap 10 px, couleur #ffffff sur le panneau sombre, durée 1,4 s et écart de 0,16 s par défaut, centrés au-dessus du libellé « Recherche d'un chauffeur à proximité… », role="status" sur le bloc d'état.
Lumen Studio Nova-V · vidéo Crédits : 42
InviteCôte bretonne au lever du soleil, 6 s

Génération de votre clip…

Durée variable — en général moins d'une minute.

③ Attente de génération dans un outil IA

QuandAprès validation d'une invite : l'interface attend la réponse d'un modèle de génération (texte, image, audio) pour une durée imprévisible.
PourquoiL'animation boucle sans dépendre d'une durée connue — une barre de progression n'est pas possible. Le rythme de 1,4 s est assez lent pour ne pas créer d'urgence, assez vif pour signaler que le système travaille.
RéglagesPoints 14 px, gap 10 px, couleur #a78bfa, durée 1,6 s, centré sous la zone de réponse vide.

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", ni aria-label, ni aria-live sur le conteneur. Les lecteurs d'écran ignorent ces cercles animés. Pour un indicateur de chargement, ajoutez role="status" et aria-label="Chargement en cours" sur la div.loader-dots ; pour un bouton en attente, préférez aria-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> (technique clip: rect(0,0,0,0) usuelle).
  • animation-play-state codé en dur à running : la valeur est inscrite dans le raccourci animation de chaque span. 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.

Chrome 84+✓ Complet
Firefox 63+✓ Complet
Safari 14.1+✓ Complet
Edge 84+✓ Complet
iOS Safari 14.5+✓ Complet
Android Chrome 84+✓ Complet

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.

HTML
<div class="loader-dots">
  <span>
  </span>
  <span>
  </span>
  <span>
  </span>
</div>
CSS
.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);
   }
}
JavaScript (fx-0422)
// Effet CSS pur — pas de JavaScript nécessaire

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
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.