Keyframes
Keyframes
Basic Keyframe Definition
@keyframes slide-in {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
Multiple Keyframes
@keyframes bounce {
0% { transform: translateY(0); }
25% { transform: translateY(-20px); }
50% { transform: translateY(0); }
75% { transform: translateY(-10px); }
100% { transform: translateY(0); }
}
Using Keyframes
.element {
animation-name: slide-in;
animation-duration: 0.5s;
}
/* Shorthand */
.element {
animation: slide-in 0.5s ease;
}
Named Keyframes
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fade-out {
from { opacity: 1; }
to { opacity: 0; }
}
Animation Properties
Animation Properties
animation-name
.element {
animation-name: slide-in;
}
animation-duration
.element {
animation-duration: 0.5s;
animation-duration: 500ms;
}
animation-timing-function
.element {
animation-timing-function: ease;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
animation-timing-function: steps(5);
}
animation-delay
.element {
animation-delay: 0.2s;
}
animation-iteration-count
.element {
animation-iteration-count: 1; /* Once */
animation-iteration-count: 3; /* Three times */
animation-iteration-count: infinite; /* Loop forever */
}
animation-direction
.element {
animation-direction: normal; /* 0% to 100% */
animation-direction: reverse; /* 100% to 0% */
animation-direction: alternate; /* 0% to 100% to 0% */
animation-direction: alternate-reverse;
}
animation-fill-mode
.element {
animation-fill-mode: none; /* No effect before/after */
animation-fill-mode: forwards; /* Stay at final state */
animation-fill-mode: backwards; /* Apply first keyframe during delay */
animation-fill-mode: both; /* forwards + backwards */
}
animation-play-state
.element {
animation-play-state: running;
animation-play-state: paused;
}
.element:hover {
animation-play-state: paused;
}
Shorthand
/* name duration timing-function delay iteration-count direction fill-mode */
.element {
animation: slide-in 0.5s ease 0.1s 1 normal forwards;
}
Animation Events (JavaScript)
element.addEventListener('animationstart', () => {});
element.addEventListener('animationiteration', () => {});
element.addEventListener('animationend', () => {});
Performance Considerations
Performance Considerations
GPU-Accelerated Properties
/* Good: Transform and opacity */
@keyframes slide-in {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
/* Bad: Layout-triggering */
@keyframes bad-slide {
from { left: -100%; }
to { left: 0; }
}
Use will-change
.animated-element {
will-change: transform, opacity;
}
Respect User Preferences
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Loading Spinner
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
Pulse Effect
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.pulse {
animation: pulse 2s ease-in-out infinite;
}
Shake Effect
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.shake {
animation: shake 0.5s ease-in-out;
}
Practice Problems
Create a reusable React component implementing CSS Animations. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for CSS Animations using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize CSS Animations for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What is the difference between transitions and animations?
2. What does animation-fill-mode: forwards do?
3. Which animation property makes an animation loop?
4. What is will-change used for?
5. Why use transform instead of left/top for animations?
Flashcards
Question
What is the difference between from/to and percentage keyframes?
Click to reveal answer
Answer
from/to is equivalent to 0%/100%. Percentages allow multiple keyframes for complex animations.
Question
What does animation-fill-mode: both do?
Click to reveal answer
Answer
Combines forwards and backwards: applies first keyframe during delay and keeps final state after completion.
Question
What is animation-direction: alternate?
Click to reveal answer
Answer
Makes the animation play forward then reverse on each iteration (0% to 100% to 0%).
Question
How do you pause an animation on hover?
Click to reveal answer
Answer
Use animation-play-state: paused on the :hover state.
Question
What properties should you animate for performance?
Click to reveal answer
Answer
Transform and opacity are GPU-accelerated. Avoid animating width, height, top, left, margin, padding.
Revision Notes
Key Takeaways
- 1.Animations use keyframes for multi-step animations
- 2.animation-fill-mode controls state before/after animation
- 3.Transform and opacity are GPU-accelerated
- 4.Always respect prefers-reduced-motion
- 5.will-change hints to browser for optimization
Interview Tips
- •Know the difference between transitions and animations
- •Understand animation-fill-mode values
- •Explain why transform is preferred over left/top
- •Be able to create common animations (pulse, shake, fade)
Cheat Sheet
CSS Animations Cheat Sheet
Keyframes
@keyframes name {
from { /* start state */ }
to { /* end state */ }
}
@keyframes name {
0% { /* start */ }
50% { /* middle */ }
100% { /* end */ }
}
Animation Properties
animation-name: name;
animation-duration: 0.5s;
animation-timing-function: ease;
animation-delay: 0.1s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-fill-mode: forwards;
animation-play-state: running;
/* Shorthand */
animation: name 0.5s ease 0.1s infinite alternate forwards;
Performance
/* Good: GPU-accelerated */
transform: translateX(0);
opacity: 1;
/* Bad: Layout-triggering */
left: 0;
width: 100px;
Accessibility
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.01ms !important; }
}