Ever noticed how some interfaces feel alive while others just... Even so, snap? That's not magic. Or it bounces. Or it fades like it's leaving the room. You click something and it glides. It's the difference between a transition and an animation — two words most people use like they're the same thing, even though they aren't That alone is useful..
I used to mix them up too. Plus, honestly, for years I'd say "add an animation" when I meant a menu sliding in. Turns out the distinction matters more than you'd think, especially if you build anything with a screen Small thing, real impact..
What Is a Transition
Here's the thing — a transition is change with a beginning and an end that's tied to a state. You start at A. Something happens. You end at B. The transition is the visual (or sometimes audio) shift between those two states That's the part that actually makes a difference..
Think of a door. Open is state B. Closed is state A. Think about it: the transition is the door swinging. Practically speaking, it's not "doing something" for the sake of it. It's moving from one real condition to another because the underlying state actually changed.
Short version: it depends. Long version — keep reading.
In practice, on the web or in apps, a transition happens when a property flips — a button goes from gray to blue, a panel goes from hidden to visible, a card goes from small to expanded. The browser or framework sees the state change and animates the in-between frames so your eye can track what happened.
Transitions Are Reactive
They don't run on their own. A transition sits there doing nothing until something triggers it. But hover a link, toggle a switch, manage to a new view — boom, transition kicks in. It's reactive by design Surprisingly effective..
Transitions Have Implicit Endpoints
You don't usually tell a transition "play for 400 milliseconds." You say "when color changes, take 0.So 3s to get there. " The start and end are defined by the before-and-after values. That's why CSS transitions feel so lightweight — you're just describing how to ease between two known states.
What Is an Animation
An animation is a sequence of frames played over time. It doesn't need a state change to exist. It can loop forever, fire once on load, or run because you told it to — not because anything in the UI flipped And it works..
A loading spinner is the classic example. Nothing changed in your app's state. The data's still loading. But the spinner spins anyway, because the animation is doing a job: telling you "hey, we're working." That's animation, not transition.
Animations Are Proactive
They run on a timeline. Here's the thing — it doesn't care if a button got clicked. You define keyframes — point A, point B, maybe point C and D — and the system plays them. It cares about time The details matter here. Practical, not theoretical..
Animations Can Be Stateful or Purely Decorative
Some animations respond to interaction (a celebratory burst when you finish a task). Others are just there: pulsing dots, floating clouds, a logo that draws itself on the homepage. None of those require a before/after state pair. They're timelines, full stop Surprisingly effective..
Why It Matters / Why People Care
Why does this difference matter? Because most people skip it — and then they build interfaces that feel either broken or chaotic Not complicated — just consistent. That's the whole idea..
If you use an animation where a transition belongs, you might end up manually coding every movement between states. That's fragile. The moment your layout shifts, your hardcoded animation breaks. A transition would've just followed the new state automatically.
And if you use a transition where an animation is needed? So naturally, you sit there wondering why your loading indicator won't move unless someone clicks something. Which means it won't. Transitions wait for a trigger that never comes Easy to understand, harder to ignore..
Real talk: getting this wrong also hurts accessibility. Screen readers and reduced-motion settings treat these differently. A transition tied to a state change is usually easier to make sense of. A looping animation can be a nightmare for someone with vestibular issues if you don't respect prefers-reduced-motion.
Turns out, the line isn't just academic. It changes how you code, how your UI feels, and whether people with disabilities can use your product And that's really what it comes down to. Worth knowing..
How It Works (or How to Do It)
Let's get into the mechanics. I'll use web examples because that's where most people trip over this, but the logic applies to mobile and game UI too.
CSS Transitions: The State-Following Approach
In CSS, a transition is declared on an element. You say which properties to watch and how long the shift should take And that's really what it comes down to..
.button {
background: gray;
transition: background 0.3s ease;
}
.button:hover {
background: blue;
}
That's it. Because of that, no "play" command. Because of that, the browser sees the background go from gray to blue and fills the gap. But no keyframes. The short version is: you describe the endpoints, CSS handles the journey Worth keeping that in mind..
You can watch multiple properties. You can delay one. But you're always describing how to move between two states, not what to do on a timer The details matter here..
CSS Animations: The Timeline Approach
Animations use @keyframes. You define what happens at 0%, 50%, 100% — or any stops you want.
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}
See the difference? Practically speaking, nothing changed in the DOM. In real terms, the spinner just... Because of that, spins. Worth adding: because time passed. In practice, you can pause it, reverse it, run it once, loop it. The animation doesn't know or care about your app's state That alone is useful..
JavaScript: Where the Lines Blur a Bit
In JS, libraries like Framer Motion or GSAP let you do both. A "transition" in Framer Motion is often a prop that animates between component states (mount/unmount, variant changes). An "animation" might be a standalone timeline you trigger with .play() And that's really what it comes down to. Nothing fancy..
The mental model stays the same though. Also, transitions follow state. Animations follow time.
The Hybrid Zone
Some things look like both. A card that flips on click? Now, the click changes state (flipped: true), so the flip is a transition. But if you add a continuous shimmer while it's flipped, that shimmer is an animation running on top. Knowing which is which helps you debug and keep performance sane It's one of those things that adds up..
Common Mistakes / What Most People Get Wrong
I know it sounds simple — but it's easy to miss. Here's where folks mess up.
Calling everything "animation." Designers hand off "animation specs" that are really just transition timings. Developers then build keyframe loops for something that should've been a 200ms ease on a state change. Overkill, and harder to maintain That alone is useful..
Assuming transitions can loop. They can't. A transition is a one-shot response to a state pair. If you need a heartbeat pulse, that's an animation. People waste hours trying to "repeat" a transition Most people skip this — try not to..
Forgetting that transitions need a trigger. Set up a transition, change the value in JS, and wonder why nothing moved — because you changed it without the element re-rendering or the class actually toggling. The state didn't flip in a way the browser noticed.
Using animations for layout changes. Say a sidebar expands. If you hardcode an animation of width: 0 to width: 240px, but later the design changes to 280px, your animation lies. A transition would've just followed the new width. This is the part most guides get wrong — they show animations for things that are fundamentally state changes The details matter here..
Ignoring performance. Animations on a loop (especially transforms and opacity) are fine if done right. But people animate top/left in keyframes forever, and the browser cries. Transitions on those same properties are just as bad — but the fix is the same: use transform and opacity.
Practical Tips / What Actually Works
Here's what actually works when you're building:
- Default to transition for anything tied to a toggle, hover, open/close, or view change. If the user did something and the UI moved from A to B, it's probably a transition.
- Reach for animation only when there's no state pair. Loading, ambient motion, celebratory effects, intros. Things that exist on a clock.
- Name them correctly in your head and in code. Call
the file card-transition.Also, css instead of card-anim. In real terms, css when it's really just a hover state. The naming forces clarity and helps the next person (or future you) not trip over the same confusion.
-
Use the right tools. CSS handles most transitions and simple animations cleanly. For orchestrated, multi-step sequences tied to app logic, a library like GSAP or Framer Motion is worth it — but don't pull in a 50kb dependency to fade a button.
-
Test both directions. A transition should feel right going forward and reversing. An animation should loop or end without a visual jump. Most bugs show up on the reverse path or the second play-through.
-
Keep motion accessible. Respect
prefers-reduced-motion. Transitions can be shortened or dropped; looping animations should pause. Motion is communication, not decoration, and not everyone can receive it the same way Most people skip this — try not to. Turns out it matters..
Conclusion
Transitions and animations aren't rivals — they're different answers to different questions. One asks "what changed?When you stop lumping them together and start mapping each effect to the thing that actually drives it, your interfaces get calmer, your code gets smaller, and your bugs get easier to find. Here's the thing — ", the other asks "what's happening? ". Build with the state in mind, and the motion takes care of itself.