Léa
votre petite-fille vous appelle
En communication · 00:47
Une balle de 50 px qui saute à 60 px, retombe en s'écrasant (1,15 × 0,85), rebondit à 25 puis 8 px et se pose, en 2 s : une seule keyframe CSS dont la courbe dépasse sa cible à chaque étape, d'où l'élasticité — zéro JavaScript, une simple pulsation si l'utilisateur réduit les animations.
Mis à jour le
Cet effet est gratuit — la catégorie Transitions en contient 52 au total, dont 9 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →
votre petite-fille vous appelle
En communication · 00:47
À toi, Jules !Touche le dé pour le lancer
4 ! Avance de 4 casesL'oie te fait rejouer
3 minutes : épaules, dos, un verre d'eau
Roulez les épaules vers l'arrière, 10 fois
Trois éléments : le cadre .md-spring-stage (250 px de haut, fond #1a1a24), la zone .md-spring qui centre, et .md-spring-ball, un disque de 50 px en dégradé indigo vers rose (#6366f1 → #ec4899). Toute la physique tient dans @keyframes mdSpring, jouée en boucle : animation: mdSpring 2s cubic-bezier(0.34, 1.56, 0.64, 1) infinite. Les étapes alternent sauts et contacts : 20 % en l'air à −60 px, étirée (0,9 × 1,1) ; 40 % au sol, écrasée (1,15 × 0,85) ; 55 % à −25 px ; 70 % au sol (1,05 × 0,95) ; 85 % à −8 px ; 100 % au repos. Chaque rebond fait à peu près 40 % du précédent, et les déformations diminuent avec lui : c'est ce qui donne l'impression d'une matière qui amortit.
La courbe fait le reste. Sa deuxième valeur, 1,56, dépasse 1 : entre deux étapes, la balle va un peu plus loin que la cible avant d'y revenir. Mesuré image par image dans Chromium 151 : sommet du premier saut à −65,8 px au lieu de −60, enfoncement de 5,8 px sous le point de repos au contact, écrasement maximal 1,17 × 0,83. Ce dépassement, appliqué à chaque segment, joue le rôle du ressort ; avec une courbe ease-in-out, la même keyframe donnerait une balle qui monte et descend sans rebondir. L'origine de la transformation reste au centre : à l'écrasement, la balle se tasse vers son milieu et son bas remonte d'environ 4 px — voir les réglages pour la poser sur un sol. Le transform seul est animé, sans recalcul de mise en page.
L'effet est un appel à l'attention qui tourne en boucle, pas une transition entre deux états : il bouge tant que quelque chose attend une action. C'est à votre page de l'arrêter quand l'action a lieu (appel décroché, dé lancé) : animation: none sur la balle la remet au repos, comme dans les trois exemples. Le cadre a sa propre classe, préfixée comme le reste de l'effet : deux effets de la bibliothèque collés sur la même page ne se réécrivent pas.
prefers-reduced-motion: reduce, la keyframe de rebond est remplacée par mdSpringFade, une pulsation d'opacité de 1 à 0,45 sur le même rythme de 2 s. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : plus aucun déplacement ni déformation (transformation identique à chaque mesure), opacité qui varie. Le signal « quelque chose attend » reste lisible sans mouvement.animation: none dès qu'elle a lieu, et ne laissez pas la balle rebondir dans une zone de la page qui n'attend rien.div vide, sans rôle. Si elle signale un appel ou un tour de jeu, écrivez-le aussi en texte à côté (« Léa vous appelle ») ; si elle sert de bouton, donnez-lui role="button", tabindex="0" et un libellé, ou mettez-la dans un vrai button.#1a1a24 du cadre ; sur un fond clair, vérifiez la teinte indigo, la plus sombre.CSS pur (@keyframes, transform, cubic-bezier avec une valeur hors de 0-1), 1,4 Ko, zéro JavaScript. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même rebond, même pulsation de remplacement sous mouvement réduit. Une courbe cubic-bezier dont l'ordonnée dépasse 1 est valide dans la norme et lue par les trois moteurs.
Sans animations CSS, la balle reste immobile au centre de son cadre, ronde et en couleur : l'élément se voit, seul le rebond manque.
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="md-spring-stage">
<div class="md-spring">
<div class="md-spring-ball"></div>
</div>
</div>
.md-spring-stage,
.md-spring-stage *,
.md-spring-stage *::before,
.md-spring-stage *::after {
box-sizing: border-box
}
.md-spring-stage {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 250px;
overflow: hidden;
position: relative;
background: rgb(26, 26, 36);
color: rgb(255, 255, 255);
font-family: sans-serif;
}
.md-spring {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.md-spring-ball {
width: 50px;
height: 50px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #ec4899);
animation: mdSpring 2s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
@keyframes mdSpring {
0%,
100% {
transform: translateY(0) scaleX(1) scaleY(1);
}
20% {
transform: translateY(-60px) scaleX(0.9) scaleY(1.1);
}
40% {
transform: translateY(0) scaleX(1.15) scaleY(0.85);
}
55% {
transform: translateY(-25px) scaleX(0.95) scaleY(1.05);
}
70% {
transform: translateY(0) scaleX(1.05) scaleY(0.95);
}
85% {
transform: translateY(-8px);
}
}
/* Mouvement réduit : ni saut ni déformation, une pulsation d'opacité garde le signal */
@media (prefers-reduced-motion: reduce) {
.md-spring-ball {
animation: mdSpringFade 2s ease-in-out infinite;
}
}
@keyframes mdSpringFade {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.45;
}
}
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Hauteur des sauts (CSS — translateY à 20 %, 55 % et 85 %) |
−60 / −25 / −8 px | Gardez un rapport proche de 0,4 entre deux rebonds pour un amorti crédible : −90 / −36 / −14 px pour une balle plus grande. Des sauts égaux donnent une balle qui ne perd jamais d'énergie. |
Écrasement et étirement (CSS — scaleX / scaleY) |
1,15 × 0,85 au premier contact, 0,9 × 1,1 en l'air | 1,3 × 0,7 donne une matière très molle (gelée) ; 1,05 × 0,95 une balle de tennis. Gardez le produit des deux proche de 1 pour que la balle semble garder son volume. |
Courbe (CSS — cubic-bezier(0.34, 1.56, 0.64, 1)) |
dépassement d'environ 10 % | 1,56 → 1,9 accentue le ressort (sommet plus haut, enfoncement plus marqué) ; 1,56 → 1 supprime le dépassement et le côté élastique. |
Durée (CSS — 2s) |
2 s par cycle complet | 1,4 s rend la balle nerveuse ; 3 s plus lourde. Pour un rebond suivi d'une vraie pause, étirez la keyframe : terminez les étapes à 60 % et laissez la balle au repos jusqu'à 100 %. |
Arrêt (CSS — animation: none) |
aucun : boucle infinie | Posé par une classe d'état (ex. .is-answered .md-spring-ball), il remet la balle au repos immédiatement. Pour finir le saut en cours, attendez l'évènement animationiteration avant de poser la classe. |
Taille et couleur (CSS — .md-spring-ball) |
50 px, dégradé #6366f1 → #ec4899 |
Tout élément peut rebondir : photo, icône, dé. Les distances étant en pixels, une balle de 100 px garde des sauts de 60 px ; augmentez-les avec la taille. |
Ajoutez une classe d'état sur un parent et la règle .is-done .md-spring-ball { animation: none; } : la balle revient aussitôt au repos. Si le saut est coupé en plein vol et que cela se voit, écoutez animationiteration sur la balle et posez la classe à ce moment-là, quand elle touche le sol en fin de cycle. Pour relancer, retirez la classe : l'animation repart du début.
C'est la courbe cubic-bezier(0.34, 1.56, 0.64, 1) : sa deuxième valeur dépasse 1, donc chaque segment va plus loin que sa cible avant d'y revenir. Mesuré : 5,8 px sous le repos au contact, sommet à 65,8 px au lieu de 60. C'est ce dépassement qui fait « ressort ». Si la balle est posée sur un trait de sol et que l'enfoncement se voit, remontez le sol de 6 px ou réduisez 1,56 à 1,3.
Ajoutez transform-origin: 50% 100% à .md-spring-ball. Par défaut, l'écrasement se fait autour du centre : au contact, le bas de la balle remonte d'environ 4 px et elle semble flotter. Avec l'origine en bas, le bas reste collé au sol et seule la hauteur s'aplatit, comme une vraie balle. Les sauts (translateY) ne changent pas.