CSS @keyframes At-Rule

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

Definition and Usage

The @keyframes at-rule defines the steps of a CSS animation. You name a keyframe list and set styles at points along the timeline, then attach that name with animation-name (or the animation shorthand).

Use from/to for a simple start and end, or percentages for middle steps. Prefer animating transform and opacity for smooth, efficient motion.

Baseline Widely available.

Standard CSS Animations feature since 2015. Keyframe names are case-sensitive and must match animation-name exactly.

Accessibility.

Respect prefers-reduced-motion — reduce or turn off continuous motion when users request less animation.

CSS Syntax

syntax.css
@keyframes <keyframes-name> {
  from | <percentage> { /* styles */ }
  to   | <percentage> { /* styles */ }
}

/* then attach the name */
.element {
  animation-name: <keyframes-name>;
  animation-duration: <time>;
}

from = 0%, to = 100%. You can list offsets in any order.

Keyframe Forms

FormDescriptionTry it
from / toStart and end of the animationTry it
percentagesMiddle steps such as 25%, 50%Try it
transformMove, scale, or rotate efficientlyTry it
opacityFade in or out over timeTry it
shared offsetsOne block for several percentagesTry it
name matchanimation-name must match the rule nameTry it

How to Use @keyframes

Define the timeline, then attach it to an element.

  1. Write an @keyframes block with a clear name.
  2. Set styles at from/to or percentage offsets.
  3. On the element, set animation-name to that same name.
  4. Add animation-duration (required for motion to run).
  5. Optionally set timing, delay, iteration, direction, and fill mode.
PieceRequired?Role
Keyframe nameYesLinks @keyframes to animation-name
At least one keyframeYesDefines styles along the timeline
animation-durationYes (to see motion)Default is 0s, so nothing moves without it
Timing / iterationNoControls easing, repeats, and direction

Live Preview

Switch keyframe styles on one box. Duration stays fixed so you can compare the motion pattern.

Each option applies a different @keyframes name via animation-name.

Preview

Using from/to background-color keyframes

CSS Examples

Each snippet focuses on @keyframes. Duration and a matching name make the motion visible.

Example 1 — from / to

Animate between a start color and an end color.

CSS
@keyframes colorChange {
  from {
    background-color: #2563eb;
  }
  to {
    background-color: #7c3aed;
  }
}

.box {
  animation: colorChange 2s ease-in-out infinite alternate;
}
Try It Yourself

How It Works

  1. Name the timeline. colorChange is the keyframe list name.
  2. Set start and end. from and to are 0% and 100%.
  3. Attach the name. animation (or animation-name) must match.
  4. Give it time. 2s sets duration; alternate plays forward and back.

Example 2 — Percentage Steps

Add middle points for a multi-step motion.

CSS
@keyframes pulseSize {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.box {
  animation: pulseSize 1.5s ease-in-out infinite;
}
Try It Yourself

How It Works

  1. Mark the timeline. 0%, 50%, and 100% are waypoints.
  2. Change one property. Here transform: scale() grows then shrinks.
  3. Interpolate between. The browser fills in values between keyframes.
  4. Loop it. infinite repeats the sequence.

Example 3 — Slide With transform

Move an element without changing layout flow.

CSS
@keyframes slideX {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(6rem);
  }
}

.box {
  animation: slideX 2s ease-in-out infinite alternate;
}
Try It Yourself

How It Works

  1. Animate transform. translateX moves the box on a compositor-friendly path.
  2. Keep layout stable. Neighbors do not reflow while it moves.
  3. Match the name. slideX appears in both @keyframes and animation.
  4. Alternate. The box slides out and back smoothly.

Edge Cases & Pitfalls

Most animation bugs are naming, duration, or cascade mistakes.

name

Names must match exactly

Keyframe names are case-sensitive. Fade and fade are different.

time

Duration defaults to 0s

Without animation-duration, the animation finishes instantly and you see no motion.

cascade

Duplicate names do not merge

If two @keyframes share a name, the last one wins. They do not cascade together.

ignore

!important is ignored

Declarations with !important inside a keyframe block are dropped.

a11y

Respect reduced motion

Use prefers-reduced-motion: reduce to limit looping or large motion for sensitive users.

Browser Support

@keyframes is a browser CSS Animations feature. Node.js, Deno, and Bun do not apply it as a layout API.

✓ Baseline · Widely available

@keyframes

Chrome 43+, Firefox 16+, Safari 9+, Edge 12+, Opera 30+, Samsung Internet 4+ (unprefixed modern support).

98% All major browsers
Google Chrome 43+
Full support
Mozilla Firefox 16+
Full support
Apple Safari 9+
Full support
Microsoft Edge 12+
Full support
Opera 30+
Full support
Samsung Internet 4+
Full support
@keyframes Widely supported

Bottom line: Safe for production. Older engines needed vendor prefixes; modern browsers use unprefixed @keyframes. Not a server runtime API.

Key Takeaways

  • Role: define animation steps; animation-name attaches them.
  • Offsets: from/to or percentages along the timeline.
  • Best props: prefer transform and opacity.
  • Tip: always set a duration, and respect reduced motion.

One line: @keyframes names the steps; animation-name + duration play them.

Frequently Asked Questions

It defines the steps of a CSS animation. You name the keyframe list, set styles at points along the timeline, then connect that name with animation-name or the animation shorthand.
from means 0% (start) and to means 100% (end). Use percentages when you need middle steps such as 25%, 50%, or 75%.
No. If several @keyframes share the same name, the last one in the CSS wins. Animations do not merge keyframes from multiple rules.
No. Declarations with !important inside @keyframes are ignored.
Prefer transform and opacity for smooth, efficient motion. Layout properties like width or margin can work but are often costlier.
It is Baseline and widely available since 2015 in Chrome, Firefox, Safari, Edge, and Opera. It is a browser CSS feature, not a Node.js API.

Next: Media Queries

Adapt styles by screen size, and gate motion with media features.

Media queries →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful