ALL DEMOS

Bouncing
ball ×4

A classic bouncing ball animation. It's simple, but not easy to get it looking realistic: the physics involved affects the ball in subtle ways. These demos have a few phases: launch, apex, then three decaying bounces, with the ball squashing on every impact and the shadow shrinking as it rises.

010 kB · NATIVECSS9 keyframes · per-frame cubic-bezier
0227 kB gz · 3.13GSAP9 tweens · power2 in / out
033 kB gz · v11Motion10-value array · times[] · ease[]
0412 kB gz · v4Anime.js8 segments · outQuad / inQuad

0.00 / 2.00 S

0 · LAUNCH
APEX
IMPACT
40%
14%
KEYFRAMES · TRANSLATE-Y
bounce.css
@keyframes ball-y {
  0%   { transform: translateY(0);
         animation-timing-function: cubic-bezier(.16,.62,.34,1) }
  26%  { transform: translateY(-150px);
         animation-timing-function: cubic-bezier(.66,.02,.84,.4) }
  48%  { transform: translateY(0);
         animation-timing-function: cubic-bezier(.16,.62,.34,1) }
  62%  { transform: translateY(-60px) }
  /* …74% 82% 88% 92% 95% 100% */
}

.ball   { animation: ball-y      2s linear infinite }
.squash { animation: ball-squash 2s linear infinite }
.shadow { animation: ball-shadow 2s linear infinite }

Ratings

Onboarding
Ergonomics
Iteration
Debugging
Realism

What I like

Nothing to install, and it only animates transform and opacity, so the browser can run it on its own thread and keep it smooth while JavaScript is busy.

What I don't

Each keyframe's timing is a percentage of a total I work out by hand, so changing the duration means redoing all of them. And transform is one property, so the travel and the squash need two nested elements.

How it's built

9 keyframes · per-frame cubic-bezier

Loading engines…