CSS animations control the movement and appearance of elements on web pages. They allow you to gradually change from one CSS style to another without using any JavaScript!
@keyframes to define the actual animation steps.animation-name and animation-duration.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
background-color: navy;
color: white;
line-height: 100px;
text-align: center;
/* Applies the 'changeColor' animation, lasting 3s, looping infinitely */
animation: changeColor 3s infinite;
}
/* Defines the steps of the animation */
@keyframes changeColor {
from { background-color: navy; }
to { background-color: lightblue; color: navy; }
}
</style>
</head>
<body>
<div class="box">Animate!</div>
</body>
</html>
CSS provides several distinct properties to give you absolute control over how an element animates.
| Property | Description |
|---|---|
@keyframes |
Specifies the animation rules and the individual style changes (the "frames"). |
animation-name |
Specifies the name of the @keyframes rule you want to bind to the element. |
animation-duration |
Specifies the time it takes for an animation to complete one cycle. |
animation-timing-function |
Specifies the speed curve of the animation (e.g., linear, ease-in-out). |
animation-delay |
Specifies a delay before the animation starts. |
animation-iteration-count |
Specifies the number of times the animation should be repeated (e.g., infinite). |
animation-direction |
Defines whether the animation plays forward, backward, or alternates back and forth. |
animation-fill-mode |
Defines what styles are applied to the element before and after the animation executes. |
animation-play-state |
Specifies whether the animation is running or paused. |
@keyframes RuleThe @keyframes rule defines how an element's styles change over time.
You can use the keywords from and to (which represent 0% and 100%), or you can use percentage values to specify multiple intermediate steps!
Syntax:
@keyframes animation-name {
0% { /* Initial Styles */ }
50% { /* Intermediate Styles */ }
100% { /* Final Styles */ }
}
The animation-name property links your element to the @keyframes sequence, and the animation-duration defines how long one loop takes.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 100px;
background-color: navy; color: white;
text-align: center; line-height: 100px;
animation-name: moveRight;
animation-duration: 2s;
animation-iteration-count: infinite;
}
@keyframes moveRight {
from { transform: translateX(0); }
to { transform: translateX(200px); }
}
</style>
</head>
<body>
<div class="box">Moving!</div>
</body>
</html>
The animation-timing-function property controls the speed curve. ease-in makes the animation start slowly and speed up, whereas linear keeps the speed perfectly constant.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 50px;
background-color: lightcoral; color: white;
text-align: center; line-height: 50px; margin-bottom: 10px;
animation-name: slide;
animation-duration: 3s;
animation-timing-function: ease-in; /* Starts slowly! */
animation-iteration-count: infinite;
}
@keyframes slide {
from { transform: translateX(0); }
to { transform: translateX(300px); }
}
</style>
</head>
<body>
<div class="box">Ease-in</div>
</body>
</html>
The animation-delay property specifies a delay before an animation starts, controlling exactly when the animation begins after the page loads.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 100px;
background-color: navy; color: white;
text-align: center; line-height: 100px;
animation-name: fadeIn;
animation-duration: 2s;
animation-delay: 1s; /* Waits 1 second before starting */
animation-iteration-count: infinite;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
</style>
</head>
<body>
<div class="box">Wait 1s...</div>
</body>
</html>
The animation-iteration-count property specifies how many times an animation should repeat. You can use a specific number (like 3) or the keyword infinite.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 100px;
background-color: lightblue; color: navy;
text-align: center; line-height: 100px; font-weight: bold;
border: 2px solid navy;
border-radius: 50%;
animation: bounce 1.5s infinite; /* Loops endlessly */
}
/* Using percentages for complex keyframes! */
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-50px); }
100% { transform: translateY(0); }
}
</style>
</head>
<body>
<br><br>
<div class="box">Bounce!</div>
</body>
</html>
The animation-direction property specifies whether an animation should play forward, backward, or alternate back-and-forth between the two directions.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 100px;
background-color: navy; color: white;
text-align: center; line-height: 100px;
animation: move 2s infinite;
/* Plays forward, then reverses smoothly! */
animation-direction: alternate;
}
@keyframes move {
from { transform: translateX(0); }
to { transform: translateX(200px); }
}
</style>
</head>
<body>
<div class="box">Back & Forth</div>
</body>
</html>
The animation-fill-mode property specifies how CSS should apply styles to its target before the animation begins (if there is a delay) and after it executes.
Setting it to forwards ensures that the element retains the final state of the animation once it is finished (instead of snapping back to its original un-animated state).
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 100px;
background-color: lightcoral; color: white;
text-align: center; line-height: 100px;
animation: moveStop 3s;
/* Prevents snapping back to 0px */
animation-fill-mode: forwards;
}
@keyframes moveStop {
from { transform: translateX(0); }
to { transform: translateX(200px); background-color: navy; }
}
</style>
</head>
<body>
<div class="box">I will stop!</div>
</body>
</html>
The animation-play-state property controls whether an animation is actively running or currently paused. This is incredibly useful for hover interactions!
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px; height: 100px;
background-color: lightblue; color: navy; font-weight: bold;
text-align: center; line-height: 100px; border: 2px solid navy;
animation: spin 4s linear infinite;
/* Starts paused */
animation-play-state: paused;
}
/* Resumes the animation when hovered */
.box:hover {
animation-play-state: running;
background-color: navy; color: white;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="box">Hover to Spin</div>
</body>
</html>
The animation shorthand property allows you to set all animation-related properties in a single line, making your CSS code cleaner and much more concise.
Syntax:
.element {
/* name | duration | timing-function | delay | iteration-count | direction | fill-mode | play-state */
animation: move 2s ease-in 1s infinite alternate forwards;
}
transform and opacity, as these are hardware-accelerated by the GPU. Animating width, height, or margins forces the browser to recalculate layout constantly, which can cause lag.prefers-reduced-motion media query.Which CSS rule is required to define the actual steps or "frames" of the animation?