Transitions, transforms, and keyframe animations
/* Shorthand */
transition: property duration timing-function delay;
/* Example */
.element {
transition: all 0.3s ease;
/* or be specific: */
transition: transform 0.3s ease, opacity 0.2s ease-in;
}
/* Longhand */
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease;
transition-delay: 0s;
transform: scale(1.3)
transform: rotate(180deg)
opacity: 0.3
background: #e74c3c
translateX(50px)
scale + rotate + color
| Transform | Code | Description |
|---|---|---|
| Translate | transform: translate(x, y) |
Move element. Also translateX(), translateY() |
| Scale | transform: scale(1.5) |
Resize. Also scaleX(), scaleY() |
| Rotate | transform: rotate(45deg) |
Spin element |
| Skew | transform: skew(10deg, 5deg) |
Slant element |
| Multiple | transform: scale(1.2) rotate(45deg) |
Chain transforms (order matters!) |
| Origin | transform-origin: center |
Set pivot point: top, center, bottom, left, right, or px/% |
/* Define the animation */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
/* Apply it */
.element {
animation: bounce 1s ease infinite;
}
/* Longhand properties */
animation-name: bounce;
animation-duration: 1s;
animation-timing-function: ease;
animation-delay: 0s;
animation-iteration-count: infinite; /* or number */
animation-direction: normal; /* reverse, alternate, alternate-reverse */
animation-fill-mode: forwards; /* none, forwards, backwards, both */
animation-play-state: running; /* or paused */
/* Bounce */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
/* Pulse */
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.7; }
}
/* Shake */
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-10px); }
75% { transform: translateX(10px); }
}
/* Spin */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Fade In */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Slide In */
@keyframes slideIn {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
/* Float */
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
/* Glow */
@keyframes glow {
0%, 100% { box-shadow: 0 0 5px currentColor; }
50% { box-shadow: 0 0 20px currentColor, 0 0 30px currentColor; }
}
| Do ✅ | Don't ❌ |
|---|---|
Animate transform and opacity |
Animate width, height, top, left |
Use will-change for heavy animations |
Overuse will-change (memory hog) |
| Keep durations 200-500ms for UI | Make everything 2 seconds long |
Use ease-out for enter, ease-in for exit |
Use linear for everything |
Test with prefers-reduced-motion |
Ignore accessibility |
/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}