CSS & Web Design

Understanding CSS @keyframes: How Animation Timing Actually Works

Keyframes Are Checkpoints, Not Continuous Motion

A @keyframes rule defines the style at specific percentage points along the animation's timeline — the browser interpolates (smoothly transitions between) the values you define at each checkpoint. You're not describing every frame of motion; you're describing key moments, and the browser fills in the motion between them.

@keyframes bounce {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-20px); }
  100% { transform: translateY(0); }
}

This defines three checkpoints: start (no offset), midpoint (20px up), and end (back to no offset) — the browser smoothly interpolates the movement between each pair.

Duration Controls Speed, Not Shape

The animation-duration property determines how long the entire cycle takes, but it doesn't change what happens at each percentage — a bounce defined the same way plays identically whether it takes 0.5 seconds or 3 seconds, just faster or slower.

Timing Functions Control the Feel

Where the percentages define what happens, the animation-timing-function defines how the motion accelerates and decelerates between those points. linear moves at a constant rate throughout; ease-in-out starts and ends slowly with faster motion in the middle; custom cubic-bezier curves allow entirely custom acceleration profiles. This is often the difference between an animation that feels mechanical versus one that feels natural.

Iteration and Direction

animation-iteration-count controls how many times it repeats (a number, or infinite for continuous looping), and animation-direction controls whether each repetition plays forward, in reverse, or alternates — useful for a pulse effect that should smoothly reverse rather than snapping back to the start each cycle.

See these properties combined visually instead of by hand?

Try the Animation Generator