Mastering CSS Animations with @keyframes

A CSS transition handles a change between two states. @keyframes becomes useful when the animation needs intermediate stages, repetition, or more deliberate timing. The effect still has to support the interface rather than merely proving that the browser can move something.
What is @keyframes?
In CSS, the @keyframes rule enables us as developers to specify how an element's style should change at different points during an animation sequence. It provides a framework for defining key steps (or frames) in an animation timeline.
Syntax
@keyframes animation-name {
0% { /* Initial styles */ }
50% { /* Midpoint styles */ }
100% { /* Final styles */ }
}Here, we define three states for the element to animate between:
0%represents the starting state of the animation.100%represents the end state.- We can define as many intermediate steps as our animation needs using percentages.
A Basic Example
As a very basic example, here's a simple animation which moves a box 300px across to the right over three seconds:
@keyframes moveRight {
0% {
transform: translateX(0);
}
100% {
transform: translateX(300px);
}
}
.box {
width: 100px;
height: 100px;
background-color: steelblue;
animation: moveRight 3s linear;
}In this example:
- The animation is called
moveRight. - The
@keyframesrule defines a starting position (translateX(0)at0%) and end position (translateX(300px)at100%). - Because this is only a simple, linear animation, we only need to define the starting and end states, the browser will calculate the movement between these two.
- This is applied to
.boxby specifying the animation name (moveRight), duration (3s), and timing function (linear).
Adding Intermediate Steps
Because we can define the state at any point within the animation duration (and accept that the browser will work it out for us), we can use intermediate steps to make our animations more dynamic.
Using my example from above, for example. If we add a step at 50%, we can put a step in where it moves the majority of the way rightwards (200px) in the first half of the animation duration, and then the last 100px at a slower pace.
@keyframes moveRight {
0% {
transform: translateX(0);
}
50% {
transform: translateX(200px);
}
100% {
transform: translateX(300px);
}
}If we apply this with the same three‑second duration as before, then the box will move 200px in the first 1.5 seconds, and then the remaining 100px during the last 1.5 seconds ‑ half the speed.
You could also use these steps ‑ for example ‑ to produce a bouncing animation like this:
@keyframes bounce {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-50px);
}
100% {
transform: translateY(0);
}
}
.bouncing-box {
animation: bounce 1s ease-in-out infinite;
}Here:
- The element moves up midway through the animation (
translateY(-50px)at50%), and returns to it's original position at the end (translateY(0)at100%). - Because we're using the infinite keyword, the animation will repeat endlessly, making the
.bouncing-boxelement bounce up and down.
Controlling Animations
Aside from defining the keyframes themselves, CSS provides several properties that allow us to control animations when using @keyframes:
animation-durationdefines how long the animation should last (e.g.,3sor500ms).animation-timing-functioncontrols the speed curve (e.g.,ease,linear,ease-in-out, etc).animation-delaydelays the start of the animation.animation-iteration-countspecifies how many times the animation runs (e.g.,1,2,infinite).animation-directiondefines whether the animation plays forwards, backwards, or alternates (e.g.,normal,reverse,alternate).
These properties can also be combined together into a single shorthand animation property, using the following syntax:
animation: <animation-name> <duration> <timing-function> <delay> <iteration-count> <direction>;For example:
animation: moveRight 3s ease-in-out 1s infinite alternate;Browser Support
By November 2017, unprefixed @keyframes was supported by the current releases of Chrome, Firefox, Edge and Safari. Older browsers still needed separate attention:
Internet Explorer 9 and earlier do not support CSS animations; IE10 supports them without a vendor prefix. Safari 4–8 needed -webkit- prefixes, with unprefixed support arriving in Safari 9. For that older Safari support, the keyframes declaration begins like this; the corresponding animation properties also need their appropriate prefixes:
@-webkit-keyframes moveRight {
0% {
transform: translateX(0);
}
100% {
transform: translateX(300px);
}
}Wrapping Up
Key Takeaways
- The
@keyframesrule defines how an animation progresses through a timeline from0%to100%. - Use animation properties like
duration,timing-function, anditeration-countto control animations. - Check the versions you need to support. The historical
-webkit-example applies to Safari before version 9, not to IE10. - With its broad support in modern browsers, CSS animations are a reliable way to enhance interactivity and design.
Use keyframes when an animation needs more than a simple transition between two states. Prefer transform and opacity for smooth visual changes, keep the sequence short enough to support the interaction, and provide a reduced‑motion alternative. The interface must remain understandable when the animation does not run.