Introduction: What Are CSS Animations?
CSS animations allow web developers to create smooth, engaging transitions and movements without JavaScript or Flash. They enable elements to gradually change from one style to another, enhancing user experience and adding visual interest to web pages. CSS animations are:
- Performance efficient – hardware-accelerated in modern browsers
- Declarative – defined entirely in CSS without scripting
- Customizable – with precise timing, duration, and behavior controls
- Accessible – can respect user preferences for reduced motion
Core Animation Concepts
The Two Animation Systems in CSS
System | Best For | Control Method |
---|---|---|
Transitions | Simple state changes, hover effects | Property-based, triggered by state changes |
Keyframe Animations | Complex, multi-step animations | Defined sequences with precise control |
CSS Transitions Properties
Property | Description | Example | Default |
---|---|---|---|
transition-property | Specifies which CSS properties to animate | transform, opacity | all |
transition-duration | Duration of the transition | 0.3s or 300ms | 0s |
transition-timing-function | How the animation progresses over time | ease-in-out | ease |
transition-delay | Delay before animation starts | 0.5s or 500ms | 0s |
transition | Shorthand for all transition properties | all 0.3s ease-in-out 0s | – |
Timing Functions
Function | Description | Visual Representation |
---|---|---|
linear | Constant speed | Straight line |
ease | Slow start, fast middle, slow end | Default, smooth curve |
ease-in | Slow start, then accelerates | Gradual start |
ease-out | Fast start, then decelerates | Gradual end |
ease-in-out | Slow start and end, fast middle | Symmetrical curve |
cubic-bezier(n,n,n,n) | Custom timing curve | Defined by four control points |
steps(n, start/end) | Stepped transitions | Discrete jumps |
CSS @keyframes Animations
Basic Syntax
@keyframes animationName {
from {
/* starting styles */
}
to {
/* ending styles */
}
}
/* OR with percentage-based keyframes */
@keyframes animationName {
0% {
/* starting styles */
}
50% {
/* middle styles */
}
100% {
/* ending styles */
}
}
Animation Properties
Property | Description | Example | Default |
---|---|---|---|
animation-name | Name of the @keyframes animation | fadeIn | none |
animation-duration | Duration of the animation | 1s or 1000ms | 0s |
animation-timing-function | How the animation progresses over time | ease-in-out | ease |
animation-delay | Delay before animation starts | 0.5s | 0s |
animation-iteration-count | Number of times to play the animation | 3 or infinite | 1 |
animation-direction | Animation direction | alternate | normal |
animation-fill-mode | Style applied before/after animation | forwards | none |
animation-play-state | Pauses or plays the animation | paused or running | running |
animation | Shorthand for all animation properties | fadeIn 1s ease-in-out 0s infinite alternate forwards | – |
Animation Direction Values
Value | Description |
---|---|
normal | Default – plays forward from 0% to 100% |
reverse | Plays backwards from 100% to 0% |
alternate | Plays forward then backward |
alternate-reverse | Plays backward then forward |
Animation Fill Mode Values
Value | Description |
---|---|
none | Default – no styles applied before or after animation |
forwards | Element retains the styles from the last keyframe |
backwards | Element applies the styles from the first keyframe during delay period |
both | Combines both forwards and backwards behavior |
Step-by-Step: Creating CSS Animations
Method 1: Simple Transition
- Select the element with CSS
- Define its default state
- Define its changed state (e.g., on hover)
- Add transition properties to control the animation
.button {
background-color: blue;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: darkblue;
}
Method 2: Keyframe Animation
- Define the @keyframes animation sequence
- Select the element with CSS
- Apply the animation properties to the element
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-20px);
}
}
.bouncing-element {
animation: bounce 1s ease infinite;
}
Animatable CSS Properties
Not all CSS properties can be animated. Here are the most commonly animated properties:
Transform Properties
transform: translate(x, y)
– Move horizontally/verticallytransform: scale(x, y)
– Resize horizontally/verticallytransform: rotate(deg)
– Rotate by degreestransform: skew(x-deg, y-deg)
– Skew along X/Y axis
Visual Properties
opacity
– Transparencycolor
– Text colorbackground-color
– Background colorbox-shadow
– Shadow effectsborder-color
– Border colorborder-width
– Border width
Spatial Properties
width
/height
– Dimensionsmargin
/padding
– Spacingtop
/left
/right
/bottom
– Positioning
Common Animation Challenges and Solutions
Challenge | Solution |
---|---|
Performance issues | • Use transform and opacity when possible<br>• Add will-change property for complex animations<br>• Use translateZ(0) or translate3d(0,0,0) to trigger hardware acceleration |
Animation not working | • Check browser compatibility<br>• Verify property is animatable<br>• Ensure proper syntax in @keyframes<br>• Check if element is display: none |
Flickering | • Use backface-visibility: hidden <br>• Add transform-style: preserve-3d |
Animations running on page load | • Use animation-play-state <br>• Add animations with JavaScript after page load<br>• Use animation delay |
Respecting reduced motion preferences | • Use @media (prefers-reduced-motion) |
Best Practices and Tips
Performance Optimization
- Stick to transform and opacity for smooth animations (these don’t trigger layout)
- Avoid animating layout properties (width, height, padding, margin) when possible
- Use
will-change
sparingly to hint browser about properties that will animate - Limit the number of animated elements on screen at once
Code Organization
- Name keyframes semantically based on their purpose (e.g.,
fadeIn
,slideUp
) - Use CSS variables for animation values that repeat or might change
- Group related animations with similar timing or purpose
Accessibility
- Always provide alternatives to motion-based interactions
- Respect user preferences with
prefers-reduced-motion
media query:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.001ms !important;
transition-duration: 0.001ms !important;
}
}
Browser Compatibility
- Use vendor prefixes or autoprefixer for older browsers
- Test across browsers as animation support varies
- Provide fallbacks for browsers without animation support
Common Animation Examples
Fade In
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.element {
animation: fadeIn 1s ease-in-out;
}
Bounce
@keyframes bounce {
0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
40% { transform: translateY(-30px); }
60% { transform: translateY(-15px); }
}
.element {
animation: bounce 2s infinite;
}
Pulse
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.element {
animation: pulse 2s infinite;
}
Spinner
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}
Resources for Further Learning
Documentation
Tools
- Animista – Pre-made CSS animations
- Cubic-Bezier.com – Custom timing function generator
- Keyframes.app – Visual animation generator