25 CSS Text Animations 12 / 25

CSS Bouncing Letters Animation

Individual letters bounce with elastic spring physics using cubic-bezier overshoot easing and staggered delays for a playful, energetic effect.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="ta-12">
  <div class="ta-12__stage">
    <div class="ta-12__text">
      <span style="--i:0">B</span><span style="--i:1">O</span><span style="--i:2">U</span><span
       style="--i:3">N</span><span style="--i:4">C</span><span style="--i:5">E</span>
      <span style="--i:6">&nbsp;</span>
      <span style="--i:7">!</span>
    </div>
  </div>
</div>
.ta-12, .ta-12 *, .ta-12 *::before, .ta-12 *::after {
  margin: 0; padding: 0; box-sizing: border-box;
}
.ta-12 ::selection { background: #f59e0b; color: #fff; }

.ta-12 {
  --bg: linear-gradient(160deg, #1a0a2e, #0d1117);
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  font-family: 'Syne', 'Helvetica Neue', sans-serif;
}

.ta-12__stage { text-align: center; }

.ta-12__text {
  font-size: clamp(3rem, 9vw, 5.5rem);
  font-weight: 900;
  letter-spacing: 0.05em;
  display: flex;
  justify-content: center;
}

.ta-12__text span {
  display: inline-block;
  color: #fbbf24;
  animation: ta-12-bounce 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) infinite alternate;
  animation-delay: calc(var(--i) * 0.09s);
  text-shadow: 0 6px 20px rgba(251, 191, 36, 0.4);
}

.ta-12__text span:nth-child(even) { color: #f43f5e; text-shadow: 0 6px 20px rgba(244, 63, 94, 0.4); }

@keyframes ta-12-bounce {
  0% {
    transform: translateY(0) scaleX(1) scaleY(1);
  }
  60% {
    transform: translateY(-28px) scaleX(0.9) scaleY(1.1);
  }
  80% {
    transform: translateY(-22px) scaleX(0.95) scaleY(1.05);
  }
  100% {
    transform: translateY(-28px) scaleX(0.9) scaleY(1.1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ta-12__text span { animation: none; transform: none; }
}

How this works

Each letter is a display: inline-block span so transform applies individually. The ta-12-bounce keyframe uses a tall translateY drop combined with a custom cubic-bezier(0.34, 1.56, 0.64, 1) easing — a curve that overshoots its target value before settling back, simulating a rubber ball's elastic rebound without requiring JS spring physics.

The squash-and-stretch illusion is enhanced by pairing the bounce with scaleX(1.2) scaleY(0.8) at the bottom contact point and scaleX(0.9) scaleY(1.1) at the peak — these scale adjustments happen in a multi-stop keyframe. Each letter gets a cascading animation-delay via the CSS custom property --i, creating the wave-of-bouncing-balls visual.

Customize

  • Increase the bounce height by changing the translateY(-30px) peak to translateY(-50px) for bigger air time.
  • Adjust the elasticity by tweaking the bezier curve — try cubic-bezier(0.34, 2.2, 0.64, 1) for extreme overshoot like a super-ball.
  • Add colour change at the bounce peak by animating color in the keyframe to a highlight hue at the 50% mark.
  • Change the animation direction to bounce from top to bottom using translateY(-30px) as the start state and animating to translateY(0).
  • Apply to a logo mark or icon element alongside the text to bounce the entire layout unit together.

Watch out for

  • Inline spans ignore transform — always set display: inline-block on each letter span or the bounce has no visible effect.
  • The cubic-bezier overshoot (y > 1) creates values outside the 0–100% property range for non-transform properties; only use it with transform where overshooting is valid.
  • Many simultaneously bouncing letters on mobile can drop frame rates; consider using animation-play-state: paused on elements outside the viewport.

Browser support

ChromeSafariFirefoxEdge
36+ 9+ 16+ 36+

cubic-bezier with y-values outside 0–1 is supported for transforms in Chrome 54+, Firefox 65+, Safari 14+. Older browsers clip the easing curve.

Search CodeFronts

Loading…