Bouncing Squares
Trois carrés de 15 px, fond #6366f1, border-radius: 0 — rebond de 20 px avec compression à 80 %, en cascade de 100 ms. Pur CSS, aucun JavaScript.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Chargement comprend 29 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le conteneur .loader-squares est un flex d'une ligne, gap: 8px, sans hauteur explicite. Ses trois enfants span mesurent chacun 15 × 15 px, fond #6366f1, border-radius: 0 — des carrés à angles francs, pas des cercles. Mesurés dans Chromium : 14,77 à 15,00 px selon la phase d'animation au moment de la capture. Aucune variable CSS, aucun JavaScript.
La keyframe squareBounce applique deux transformations simultanément à 50 % du cycle : translateY(-20px) et scale(.8), puis revient à translateY(0) scale(1) aux deux extrémités. Mesurée au sommet dans Chromium, la matrice affiche scale(0,800) et un décalage vertical de −20 px : le carré remonte exactement 20 px et occupe alors 12 × 12 px. Le scale(.8) n'est pas un effet de profondeur — c'est la technique du « squash-and-stretch » : un objet élastique qui ralentit en haut de sa course se comprime légèrement, ce que cette seule valeur reproduit sans ombre ni élément secondaire.
Les délais positifs 0 s, 0,1 s et 0,2 s décalent les trois carrés de 100 ms l'un après l'autre. Comme les délais CSS positifs ne jouent qu'au premier cycle, les cycles suivants se superposent en cascade permanente : au régime établi, le premier carré est au sommet quand le deuxième atteint la mi-montée et le troisième quitte le sol. L'œil perçoit une vague de gauche à droite à 1 Hz (un cycle complet par seconde).
Accessibilité
- prefers-reduced-motion absent du code : mesuré avec émulation
reducedMotion: 'reduce', les trois animations restent à l'étatrunning. Il n'y a aucune règle@media (prefers-reduced-motion: reduce). Pour respecter la préférence, ajoutez@media (prefers-reduced-motion: reduce) { .loader-squares span { animation: none; } }— les carrés deviennent statiques, repli honnête pour un indicateur. - role, aria-live et texte alternatif absents : pour un indicateur de chargement fonctionnel, ajoutez
role="status" aria-live="polite"sur.loader-squareset un<span class="sr-only">Chargement…</span>à l'intérieur ; retirez-le dès la fin du chargement. Si le loader est purement décoratif (un texte visible indique l'état), posezaria-hidden="true"sur le conteneur. - Contraste :
#6366f1sur#0a0a0f(fond du site) = 4,5:1 — au-dessus du seuil 3:1 des composants graphiques non textuels (WCAG 1.4.11). Vérifiez avec votre propre fond si vous changez la couleur. - Intégration : les trois
spanforment une boîte de 61 × 15 px au repos (mesurée : 3 × 15 px + 2 × 8 px = 61 px). Lors du rebond, les carrés débordent de 20 px vers le haut — prévoyez au moins 35 px de hauteur dans le conteneur parent et évitezoverflow: hiddensur ce dernier.
Compatibilité navigateur
Animations CSS et transformations 2D : propriétés disponibles dans tous les navigateurs courants depuis 2012. Aucun JavaScript, aucune variable CSS, aucune dépendance.
Sans prise en charge des @keyframes CSS, les trois carrés restent immobiles à leur position de repos. Aucun contenu n'est perdu, mais l'indicateur cesse de signaler — prévoyez un texte alternatif si l'état de chargement est fonctionnel.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="loader-squares">
<span></span>
<span></span>
<span></span>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Couleur (CSS — background: #6366f1) |
#6366f1 | Couleur de remplissage des trois carrés. Modifiez la valeur sur .loader-squares span pour les changer tous d'un coup. Pour des couleurs par carré, ajoutez :nth-child(1), (2), (3) avec chacun leur background. |
Taille (CSS — width: 15px; height: 15px) |
15 × 15 px | Dimensions des carrés. Changez les deux ensemble pour garder la forme carrée. 8 px pour un bouton ; 24 px pour un grand indicateur. L'amplitude de saut reste absolue : ajustez translateY en proportion. |
Amplitude de montée (CSS — translateY(-20px)) |
−20 px | Hauteur maximale atteinte à 50 % du cycle, en valeur absolue. Avec des carrés de 8 px, -10px garde les proportions. -30px avec 15 px allonge la trajectoire sans changer la durée, ce qui rend le mouvement visuellement plus rapide. |
Compression au sommet (CSS — scale(.8)) |
0,8 (80 % de la taille) | Facteur de mise à l'échelle à mi-animation. scale(1) supprime le squash-and-stretch : les carrés montent sans rétrécir — effet plus mécanique. scale(.6) accentue la compression et rend l'animation plus expressive. |
Durée du cycle (CSS — animation: 1s) |
1 s | Durée d'un rebond complet par carré. .7s donne un rythme nerveux ; 1.4s un mouvement posé. Le décalage relatif (100 ms sur 1 s = 10 % du cycle) reste proportionnel si vous modifiez aussi les délais. |
Décalage entre carrés (CSS — animation-delay: .1s et .2s) |
0 s / 0,1 s / 0,2 s | 100 ms d'écart entre chaque carré, soit 10 % du cycle. .15s et .3s élargissent la cascade (15 %) ; 0s pour les trois les synchronise en un saut simultané. |
Espacement (CSS — gap: 8px) |
8 px | Espace entre les carrés. 4px pour un groupe compact (bouton) ; 12px pour aérer l'indicateur. Largeur totale au repos : 3 × taille + 2 × gap — avec 15 px et 8 px, 61 px. |
FAQ
scale(.8) à 50 % reproduit le « squash-and-stretch » : un objet élastique qui décélère en haut de sa course se comprime légèrement. Ici, la réduction à 80 % de la taille suffit à créer cette illusion sans ombre ni calque supplémentaire. Retirez le scale et les carrés montent en ligne droite : visuellement plus sec, moins dynamique.border-radius: 50%), fx-0433 des carrés (border-radius: 0). Transformation : fx-0422 passe de scale(0) à scale(1) — les points apparaissent et disparaissent — alors que fx-0433 combine translateY et scale(.8) sans jamais réduire à zéro. Timing : fx-0422 utilise des délais négatifs (−0,32 s et −0,16 s) qui entrent immédiatement en régime ; fx-0433 utilise des délais positifs (0,1 s et 0,2 s) qui créent un démarrage progressif visible au premier chargement.<span></span> dans le HTML et la règle .loader-squares span:nth-child(4) { animation-delay: .3s } (et :nth-child(5) { animation-delay: .4s } pour cinq). Le CSS de base ne change pas : tous les span héritent de .loader-squares span. Largeur totale : 4 × 15 px + 3 × 8 px = 84 px ; 5 × 15 px + 4 × 8 px = 107 px.