Bounce Path
A 20 px green ball makes five lower and lower bounces (80, 40, 30, 15 then 7.5 px high), rolls along the ground line and stops, in 3 s, then starts again: the damping of an object losing its energy, in CSS only, no JavaScript — and a ball resting at the top of the first bounce when the user reduces motion.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →
3 usage examples



How it works
The .fx-0036-root root (background #0a0a0f, at least 300 px tall) centers a 300 × 220 px .mp-bounce-scene. An <svg> draws the whole trajectory in very faint dots: five arcs (quadratic Bézier curves) that all start from the ground at y = 180 and rise to 80, 40, 30, 15 then 7.5 px, followed by a 50 px straight line where the ball rolls. The 2 px .mp-bounce-floor ground line sits at bottom: 28px, exactly under the ball when its center touches y = 180: measured, the bottom of the ball and the top of the ground match to the pixel in Chromium 151, Firefox 153 and WebKit 26.
The .mp-bounce-ball (#10b981 → #059669 gradient, green glow) gets the same path as offset-path: path(…) and an animation that takes offset-distance from 0 to 100% in 3 s, looping. Its center sits on the path: no negative margin, so the ball runs exactly over the dots. At the end of the roll, the loop starts over: the ball reappears on the left, in the air at the foot of the first arc.
The ease-in-out easing applies to the whole trip, not to each bounce: the ball starts slowly, is fastest in the middle of the series, then slows down during the small bounces and the roll. A real ball would slow down at the top of each arc. The result is stylized, and that is what keeps it readable: the bounces shrink, the momentum fades, with no physics computation and no JavaScript. For physical motion, you would need one animation per bounce, or a script.
Accessibility
- Reduced motion: under
prefers-reduced-motion: reduce, a block scoped to.fx-0036-rootstops the ball at the top of the first bounce (offset-distance: 19.7%), above the dotted trajectory: the shrinking bounces still read. Measured: 0% of pixels change over 0.8 s in Chromium, Firefox and WebKit, versus 0.75% in normal mode. - Decorative content: the ball carries no information; the svg and the empty
divs are ignored by screen readers. If the bounces illustrate a figure (a number of bounces, an energy loss), write it next to the scene. - Contrast: the green ball stands out on the dark background; the path (10% opacity) and the ground (8%) are deliberately subtle. On a light background, darken them (see "Customize").
- Rhythm: a 3 s loop, no flashing; the restart is the ball jumping back, not a flash of light.
Browser compatibility
CSS only: offset-path: path() and animated offset-distance, no JavaScript, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26 (Safari's engine): ball positions identical to a quarter of a pixel, ball-ground contact to the pixel, same stop under reduced motion. Not checked on a real Safari.
A browser without offset-path leaves the ball still at the top left of the scene, above the dotted trajectory and the ground line, which stay visible.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0036-root">
<div class="mp-bounce-scene">
<svg viewBox="0 0 300 220" fill="none">
<path d="M20,180 Q60,20 100,180 Q130,100 160,180 … L280,180" … />
</svg>
<div class="mp-bounce-ball"></div>
<div class="mp-bounce-floor"></div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Ball color (CSS — .mp-bounce-ball) |
#10b981 → #059669 gradient, green glow | Change the background and the box-shadow color; on a light background, replace the glow with a small shadow. |
Speed (CSS — 3s in the animation) |
3 s for the whole series | 2 s for a lively ball, 4 to 5 s for a demonstration. The series stays the same: only the tempo changes. |
Easing (CSS — ease-in-out) |
ease-in-out over the whole trip | linear gives a constant, more mechanical speed; ease-out throws the ball fast then lets it fade, close to a skipping stone. |
| Bounce shape (HTML + CSS) | 5 arcs of 80, 40, 30, 15 and 7.5 px, then 50 px of rolling | The path is written twice, in the svg path d and in the offset-path: change both. Keep the arcs at y = 180 so the ball touches the ground. |
Ground line (CSS — .mp-bounce-floor) |
2 px, bottom: 28px, white at 8% | Its position matches the bottom of the ball (path ground at 180 + 10 px radius). If you change the ball size or the ground height, adjust bottom. |
Background (CSS — .fx-0036-root) |
#0a0a0f | Change or remove the background to set the scene on your page; then darken the path and the ground. |
FAQ
infinite with 1 and add forwards: animation: 3s ease-in-out 0s 1 normal forwards running mpOrbit. The ball ends on the right, at the end of the roll, and stays there. To replay it on click, remove and re-add the animation with a class.