Click any item to expand the explanation and examples.
π Transitions
transition β animate property changes transition
/* Shorthand: property duration timing-function delay */
.button {
background: #3b82f6;
transition: background 0.3s ease;
}
.button:hover {
background: #2563eb;
}
/* Multiple properties */
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
/* All properties (use sparingly β can be slow) */
.element {
transition: all 0.3s ease;
}
Timing functions transition
transition-timing-function: ease; /* Default β slow start, fast, slow end */ transition-timing-function: linear; /* Constant speed */ transition-timing-function: ease-in; /* Slow start */ transition-timing-function: ease-out; /* Slow end */ transition-timing-function: ease-in-out; /* Slow start and end *//* Custom cubic bezier / transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); / Bounce */
/* Steps (for sprite animations) */ transition-timing-function: steps(4);
What can you transition? transition
/* β Performant (GPU-accelerated) */ transform /* translate, rotate, scale */ opacityFor best performance, stick to/* β Works but slower */ background-color, color, border-color width, height, padding, margin font-size, letter-spacing box-shadow, border-radius
/* β Canβt transition / display / Use opacity + visibility instead */ background-image font-family
transform and opacity.
π¬ Keyframe Animations
@keyframes β define animations keyframes
/* Define the animation */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Apply it */
.element {
animation: fadeIn 0.5s ease forwards;
}
/* With percentages */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.element {
animation: bounce 1s ease infinite;
}
animation properties keyframes
/* Shorthand: name duration timing delay count direction fill mode */ animation: slideIn 0.5s ease 0s 1 normal forwards;/* Individual properties / animation-name: slideIn; animation-duration: 0.5s; animation-timing-function: ease; animation-delay: 0.2s; animation-iteration-count: infinite; / or a number / animation-direction: alternate; / normal, reverse, alternate / animation-fill-mode: forwards; / none, forwards, backwards, both / animation-play-state: paused; / running, paused */
/* Multiple animations */ animation: fadeIn 0.5s ease, slideUp 0.5s ease;
forwards keeps the final state after animation ends. Without it, the element snaps back.
β‘ Common Patterns
Fade in pattern
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
animation: fadeIn 0.5s ease forwards;
}
Spinner / loading pattern
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 24px;
height: 24px;
border: 3px solid #e5e7eb;
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
Pulse pattern
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.skeleton {
background: #e5e7eb;
animation: pulse 2s ease-in-out infinite;
}
Slide in from side pattern
@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.slide-in {
animation: slideInRight 0.3s ease forwards;
}
Staggered children pattern
.list-item {
opacity: 0;
animation: fadeIn 0.4s ease forwards;
}
.list-item:nth-child(1) { animation-delay: 0.0s; }
.list-item:nth-child(2) { animation-delay: 0.1s; }
.list-item:nth-child(3) { animation-delay: 0.2s; }
.list-item:nth-child(4) { animation-delay: 0.3s; }
/* Or with custom properties */
.list-item {
animation-delay: calc(var(βi) * 0.1s);
}
Respect user preferences a11y
/* Disable animations for users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Always include this. Some users get motion sickness from animations.