Animation Direction
Control animation playback direction — normal, reverse, alternate, and alternate-reverse for natural motion.
Animation Direction
The animation-direction property controls which direction the animation plays each cycle. This is especially useful with repeating animations to create natural back-and-forth motion.
The Four Direction Values
| Value | Behavior | Cycle Pattern |
|---|---|---|
normal | Plays forward every time | 0%→100%, 0%→100%, 0%→100% |
reverse | Plays backward every time | 100%→0%, 100%→0%, 100%→0% |
alternate | Forward, then backward, then forward… | 0%→100%, 100%→0%, 0%→100% |
alternate-reverse | Backward, then forward, then backward… | 100%→0%, 0%→100%, 100%→0% |
normal (Default)
@keyframes slideRight {
from { transform: translateX(0); }
to { transform: translateX(200px); }
}
.box {
animation: slideRight 1s ease infinite;
animation-direction: normal;
}
/* Jumps back to start, slides right, jumps back, slides right... */
alternate — Smooth Back-and-Forth
.box {
animation: slideRight 1s ease infinite alternate;
}
/* Slides right → slides back left → slides right → ...
No jumping! Smooth continuous motion */
alternate is the most commonly used direction for looping animations because it eliminates the jarring jump back to start.
reverse — Play Backwards
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Create a fadeOut by reversing a fadeIn */
.element-leaving {
animation: fadeIn 0.3s ease reverse forwards;
}
/* Plays from opacity: 1 → opacity: 0 */
Using reverse lets you reuse the same keyframes for opposite effects instead of defining separate @keyframes fadeOut.
Practical Example: Floating Element
@keyframes float {
0% { transform: translateY(0); }
100% { transform: translateY(-20px); }
}
.floating-icon {
animation: float 3s ease-in-out infinite alternate;
}
/* Gently floats up and down — the alternate direction
makes it drift up then smoothly drift back down */
Practical Example: Breathing Glow
@keyframes glow {
from {
box-shadow: 0 0 5px rgba(52,152,219,0.3);
}
to {
box-shadow: 0 0 20px rgba(52,152,219,0.8),
0 0 40px rgba(52,152,219,0.4);
}
}
.active-indicator {
animation: glow 2s ease-in-out infinite alternate;
}
Practical Example: Swinging Pendulum
@keyframes swing {
0% { transform: rotate(-30deg); }
100% { transform: rotate(30deg); }
}
.pendulum {
transform-origin: top center;
animation: swing 1.5s ease-in-out infinite alternate;
}
Direction + Timing Function Interaction
When using alternate, the timing function also reverses on the backward cycle:
ease-inon the forward pass becomesease-outon the backward pass- This creates naturally smooth back-and-forth motion
ease-in-outstays symmetric in both directions — often the best choice foralternate
Key Takeaways
normalplays forward each cycle (default)alternatecreates smooth back-and-forth motion — best for looping animationsreverselets you reuse keyframes for opposite effects (e.g., fadeIn → fadeOut)- Combine
alternatewithinfinitefor natural breathing, floating, and swinging effects - The timing function automatically reverses with
alternatefor symmetric motion