There’s a reason stop-motion animation still hits different. It’s the imperfection. Every frame is slightly off from the last — a tiny rotation, a subtle shift, a flicker of light that the animator’s hand introduced without meaning to. Your brain registers all of it.
The Digital Smooth Problem
CSS transitions default to smooth. Easing functions create buttery motion that looks nice and feels nothing. The eye slides right past it. Smooth is forgettable.
What we want is the opposite. We want motion that makes you feel like you’re watching a projector with a slightly bent reel.
Implementing Jitter
The core technique is simple. A CSS keyframe animation that applies tiny random translations and rotations at high frequency:
@keyframes jitter {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(-1px, 1px) rotate(-0.3deg); }
50% { transform: translate(1px, -1px) rotate(0.2deg); }
75% { transform: translate(-1px, 0) rotate(0.1deg); }
}
Apply it to elements that should feel alive. Banners, headings, cards. Not everything — that’s noise. But the right elements, at the right frequency, create an energy that static pages can’t match.
Flicker and Glitch
Layer flicker on top of jitter for headings. The flicker animation modulates opacity at irregular intervals, simulating a projector bulb or a fluorescent tube on its last legs.
Glitch effects use clip-path to slice elements and offset color channels. Use sparingly — a glitch that plays constantly loses its power. A glitch that fires every few seconds is an event.
The Rule
All motion should feel mechanical, not fluid. Steps, not curves. Sudden, not gradual. If your animation would look at home on a Material Design site, it’s wrong.