Spring animation

스프링 애니메이션

Motion computed from physical quantities — stiffness, damping — instead of a fixed duration. It overshoots the target and settles with a bounce.

Also known as: Physics-based animationDamped spring
···
html
<div class="track"><i class="ball"></i><i class="target"></i></div>
css
.track{position:relative;width:min(78%,420px);height:26px;--final:calc(100% - 26px)}
.track::before{content:'';position:absolute;top:50%;left:0;right:0;height:2px;margin-top:-1px;background:var(--line);border-radius:2px}
.target{position:absolute;top:50%;right:13px;width:2px;height:34px;margin-top:-17px;background:var(--line)}
.ball{position:absolute;top:50%;left:0;width:26px;height:26px;margin-top:-13px;border-radius:50%;background:var(--accent);
  box-shadow:0 4px 10px rgba(0,0,0,.2);animation:spring 2.6s cubic-bezier(.2,.9,.3,1) infinite}
@keyframes spring{
  0%{left:0}
  30%{left:calc(var(--final) + 26px)}
  46%{left:calc(var(--final) - 10px)}
  60%{left:calc(var(--final) + 12px)}
  72%{left:calc(var(--final) - 5px)}
  84%{left:calc(var(--final) + 6px)}
  100%{left:var(--final)}
}

A cubic-bezier curve always finishes at a fixed duration, but a spring lets physics decide when it stops. Higher stiffness moves faster and snaps harder; lower damping oscillates longer.

Tools like Framer Motion, React Spring, and iOS's UISpringTimingParameters use this model. The key difference from duration-based animation: if the user interrupts or reverses mid-drag, a spring continues naturally from its current velocity.

The circle below overshoots its target each time and settles with a wobble — the lower the damping, the longer it keeps oscillating.

When to use

Best for motion that must react immediately to gestures and drags. For page transitions where exact timing matters, duration-based easing is usually better.