- CSS Tutorial
- CSS Introduction
- CSS Syntax
- CSS Comments
- CSS Selectors
- CSS Fonts
- CSS Colors
- CSS Backgrounds
- CSS Box Model
- CSS Borders
- CSS Margins
- CSS Padding
- CSS Text
- CSS Images
- CSS Links
- CSS Lists
- CSS Tables
- CSS Outline
- CSS Icons
- CSS Display
- CSS max-witdh
- CSS Position
- CSS z-index
- CSS Overflow
- CSS Float
- CSS Align
- CSS Opacity
- CSS Navigation Bar
- CSS Dropdowns
- CSS Forms
- CSS Units
- CSS !important
- CSS Specificity
- CSS Combinators
- CSS inline-block
- CSS Hover
- CSS Cursors
- CSS Selectors
- CSS Type Selector
- CSS Class Selector
- CSS ID Selector
- CSS Attribute Selector
- CSS Pseudo-class Selector
- CSS Pseudo-element Selector
- CSS Universal Selector
- CSS Advanced
- CSS Text Formatting
- CSS Gradients
- CSS Shadow
- CSS Rounded Corners
- CSS Text Effects
- CSS 2D Transform
- CSS 3D Transform
- CSS Border Images
- CSS Inherit
- CSS Transitions
- CSS Animations
- CSS Box Sizing
- CSS Tooltip
- CSS Masking
- CSS Pagination
- CSS Styling Images
- CSS object-fit
- CSS object-position
- CSS Buttons
- CSS Multiple Columns
- CSS Variables
- CSS Flexbox
- CSS Grid
- CSS Media Queries
CSS Animations
While CSS transitions are great for simple "Point A to Point B" changes, CSS animations take things further. They allow you to create complex, multi-step sequences without needing JavaScript. By defining keyframes, you can control an element's appearance at any point during its timeline, creating everything from subtle loading indicators to immersive storytelling effects.
Keyframe Animation Syntax
To build an animation, you need two things: a @keyframes rule that defines the stages of the animation, and the animation property applied to the HTML element.
@keyframes button-bounce rather than generic ones like @keyframes anim1. It makes your CSS much easier to debug later.
Syntax for Keyframes
@keyframes animationName {
from {
/* Starting state (0%) */
opacity: 0;
}
to {
/* Ending state (100%) */
opacity: 1;
}
/* For more control, use percentages to define intermediate steps */
0% { transform: scale(1); }
30% { transform: scale(1.1); }
100% { transform: scale(1); }
}
from/to and percentages in the same keyframe block, it can become confusing. Stick to percentages if you need more than two steps.
Applying Animations to Elements
Defining the keyframes isn't enough; you have to tell an element to use them. You can do this using the longhand properties for clarity or the shorthand property for efficiency.
Syntax for Animation Property
.element {
animation-name: slideIn;
animation-duration: 2s; /* How long the cycle lasts */
animation-timing-function: ease-in-out; /* The acceleration curve */
animation-delay: 0.5s; /* Wait time before starting */
animation-iteration-count: infinite; /* How many times to repeat */
animation-direction: alternate; /* Go back and forth */
animation-fill-mode: forwards; /* Stay at the last frame when done */
animation-play-state: running; /* Can be paused via JS */
}
animation-duration. By default, it is 0s, meaning the animation will technically run but you’ll never see it.
Animation Properties
1. animation-name
This links your element to the @keyframes identifier you created.
2. animation-duration
Measured in seconds (s) or milliseconds (ms). This defines the total time one single cycle takes to complete.
3. animation-timing-function
Controls the "pacing" of the animation. linear is constant, while ease-in-out feels more natural because it starts slow, speeds up, and slows down at the end. For custom physics, you can use cubic-bezier(n, n, n, n).
4. animation-delay
Useful for staggering animations in a list. For example, you can give each list item a slightly higher delay to create a "waterfall" effect.
5. animation-iteration-count
How many times the animation runs. Use a number (e.g., 3) or the keyword infinite for loops.
6. animation-direction
Determines if the animation plays forward, backward (reverse), or switches back and forth (alternate).
7. animation-fill-mode
One of the most important properties. By default, an element snaps back to its original state after an animation ends. forwards ensures the element stays exactly where the animation finished.
8. animation-play-state
A simple toggle that can be running or paused. This is extremely useful when paired with user interactions like hovering or clicking.
Example of CSS Animation
In this real-world example, we'll create a "sliding box" that moves horizontally. Instead of changing the left property (which is bad for performance), we use transform.
@keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100px);
}
}
.box {
width: 100px;
height: 100px;
background-color: #3498db;
border-radius: 8px;
/* Shorthand: name | duration | timing | iteration | direction */
animation: slide 2s ease-in-out infinite alternate;
}
transform (scale, rotate, translate) and opacity is much smoother than animating width, height, or top because they are handled by the GPU rather than the main CPU thread.
Animating Multiple Properties
You aren't limited to moving one thing. You can change colors, sizes, and positions all within the same timeline to create a complex effect.
@keyframes status-pulse {
0% {
transform: scale(1);
background-color: #e74c3c; /* Red */
box-shadow: 0 0 0 0px rgba(231, 76, 60, 0.7);
}
70% {
transform: scale(1.05);
background-color: #c0392b;
box-shadow: 0 0 0 10px rgba(231, 76, 60, 0);
}
100% {
transform: scale(1);
background-color: #e74c3c;
}
}
.notification-dot {
width: 20px;
height: 20px;
border-radius: 50%;
animation: status-pulse 2s infinite;
}
Using @keyframes
Keyframes allow you to define intermediate styles at different points. This is perfect for "pulsing" or "shaking" effects where the element needs to return to its original state.
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.heart-icon {
display: inline-block;
animation: pulse 1s ease-in-out infinite;
}
Controlling Animation States
While CSS handles the visual movement, JavaScript is great for controlling when that movement happens based on logic. A common pattern is pausing a background animation when a user hovers over a specific area.
// Select the element
const element = document.querySelector('.element');
// Pause on mouse enter
element.addEventListener('mouseenter', () => {
element.style.animationPlayState = 'paused';
});
// Resume on mouse leave
element.addEventListener('mouseleave', () => {
element.style.animationPlayState = 'running';
});
.style directly in JS, toggle a class like .is-paused that has animation-play-state: paused; defined in your CSS. It keeps your concerns separated.
Tips for Using CSS Animations
- Performance: Stick to
transformandopacity. If you animate properties that trigger "layout" (likemarginorheight), the browser has to recalculate the entire page layout on every frame, leading to lag. - Browser Compatibility: While modern browsers support CSS animations fully, legacy projects might require
-webkit-prefixes for Safari or older versions of Chrome. Always check CanIUse.com if you are targeting older enterprise browsers. - Accessibility: Some users have vestibular disorders and are sensitive to motion. Respect the
prefers-reduced-motionmedia query to disable or simplify animations for those users.