5 Pure CSS2 with JSPublished 2026-10-05Free · no sign-up
Seven bounces: a ball that squashes on landing, a chevron hinting at more content, a cart badge that bounces when an item is added, a card that drops in with a bounce, letters that hop in turn, a button with a springy release and icons that hop when their row is hovered.
A ball that falls, squashes on impact and stretches as it leaves the ground, the first rule of animation applied in CSS. The fall uses ease-in and the rise ease-out, set per keyframe with animation-timing-function, so it accelerates like real gravity.
A chevron at the bottom of a hero bounces gently to suggest there is more below. It is a link to the next section with a visible text label, so it also works as a skip link, and the bounce stops for reduced motion.
Adding an item bumps the cart count and the badge bounces, confirming the action where the eye is not looking. The count is part of the cart link's accessible name, and a polite live region says Added to cart for screen reader users.
var n = document.querySelector('.bn3 .n'), cart = document.querySelector('.bn3 .cart'), live = document.querySelector('.bn3 .sr'), k = 2;
document.querySelector('.bn3 button').onclick = function () { k++; n.textContent = k; cart.setAttribute('aria-label', 'Cart, ' + k + ' items'); live.textContent = 'Added to cart. ' + k + ' items.'; n.classList.remove('pop'); void n.offsetWidth; n.classList.add('pop'); };
04. Bounce-In Entrance
BounceEntrance
A success card drops in with a bounce, overshooting slightly and settling, made with three keyframes rather than a library. The card's message is in a role="status" region so its appearance is announced, whatever the animation does.
View code
<div class="bn4"><div class="card" role="status"><b>Payment received</b><span>Receipt sent to your email.</span></div><button>Replay</button></div>
var c = document.querySelector('.bn4 .card');
document.querySelector('.bn4 button').onclick = function () { c.style.animation = 'none'; void c.offsetWidth; c.style.animation = ''; };
05. Bouncing Letters
BounceText
The letters of a short word hop one after another and land with a squash, a cheerful touch for a kids brand or a 404 page. Letters are aria-hidden spans and the word is repeated as visually hidden text so it is read normally.
The button squashes when pressed and springs back past its size before settling, thanks to a cubic-bezier with an overshoot value above 1 on the release transition. The press itself uses a quick ease-out so it never feels laggy.
Icons in a feature list hop once when their row is hovered or focused, a small reward that draws attention to the row under the pointer. The hop is a short keyframe animation started by the hover state, so it plays once each time.
A bounce looks real when the fall speeds up and the rise slows down. Set animation-timing-function: ease-in on the falling keyframe and ease-out on the rising one; the timing function applies until the next keyframe.
Squash and stretch
Scale an object wider and shorter at the moment of impact and taller and thinner in flight. Keep its volume roughly constant, so 1.25 by 0.75 rather than 1.25 by 1.
Overshoot with cubic-bezier
A cubic-bezier() whose second or fourth value is above 1 overshoots its target before settling, which gives a spring without extra keyframes.
Bounce for feedback
A badge that bounces when its number changes confirms an action out of the corner of the eye. Pair it with a live region so the change is also announced.
Frequently asked questions
How do I replay a bounce?
Remove the animation, force a reflow by reading offsetWidth, and set it again, as the demos with Replay buttons do.
Are infinite bounces annoying?
Often. Keep looping bounces for small hints and stop them on reduced motion.
Do I need a physics library?
Not for these. Keyframes with easing cover most interface bounces.