Timing and spacing

타이밍과 스페이싱

How many drawings an action takes (timing) and how tightly they cluster (spacing) decide not just speed but weight and personality.

Also known as: Timing (12 principles)Spacing chart
···
html
<div class="rows">
  <div class="row">
    <span class="tag">4 in-betweens — fast, light</span>
    <div class="track" id="trackFast"><i class="ball fast"></i></div>
  </div>
  <div class="row">
    <span class="tag">14 in-betweens — slow, heavy</span>
    <div class="track" id="trackSlow"><i class="ball slow"></i></div>
  </div>
</div>
css
.rows{position:absolute;inset:12% 8%;display:flex;flex-direction:column;justify-content:space-around}
.row{display:flex;flex-direction:column;gap:8px}
.tag{font:700 10px/1 ui-monospace,monospace;color:var(--muted)}
.track{position:relative;height:20px}
.track::before{content:'';position:absolute;top:50%;left:0;right:0;height:2px;margin-top:-1px;background:var(--line)}
.tick{position:absolute;top:50%;width:2px;height:10px;margin-top:-5px;background:var(--muted);opacity:.5}
.ball{position:absolute;top:50%;left:0;width:20px;height:20px;margin-top:-10px;border-radius:50%;box-shadow:0 2px 6px rgba(0,0,0,.2);
  animation:moveTrack 2.2s infinite}
.ball.fast{background:var(--accent);animation-timing-function:steps(4)}
.ball.slow{background:var(--accent-2);animation-timing-function:steps(14)}
@keyframes moveTrack{from{left:0}to{left:calc(100% - 20px)}}
js
function ticks(container, n) {
  for (let i = 0; i <= n; i++) {
    const f = i / n;
    const t = document.createElement('i');
    t.className = 'tick';
    t.style.left = 'calc((100% - 20px) * ' + f + ' + 9px)';
    container.appendChild(t);
  }
}
ticks(document.getElementById('trackFast'), 4);
ticks(document.getElementById('trackSlow'), 14);

Cover the same distance in just 4 drawings and the motion reads light and quick; cover it in 14 closely-packed drawings and it reads heavy and unhurried. That's timing (how many drawings, how long it takes) and spacing (how far apart they are) working together — the two always move as a pair.

Animators sketch this out ahead of time as a spacing chart: plot an object's position at several moments on one sheet, and the gaps between the dots alone tell you whether you're looking at a skittish mouse or a lumbering elephant.

In CSS, animation-timing-function: steps(n) implements this directly — a small n means big, sparse jumps (light, fast); a large n means many tight steps (heavy, smooth).

The top ball below moves in 4 steps — the gaps are wide, so it reads as light and bouncy. The bottom ball moves in 14 steps over the same distance and duration — the gaps are tight, so it reads as heavier and smoother.

When to use

Tune the step count when you want a character or mascot to have personality. For everyday UI transitions, a smooth easing curve is usually better — reach for steps() only when you deliberately want weight, or a mechanical feel.