CSS @keyframes At-Rule

Beginner
⏱️ 7 min read
📚 Updated: Jul 2026
🎯 4 Examples
At-Rules

What You’ll Learn

The @keyframes at-rule defines the steps of a CSS animation. Give it a name, describe how styles change over time, then apply it with the animation property.

01

Keyframes

Define steps.

02

from / to

Start & end.

03

0% – 100%

Timeline.

04

animation

Apply it.

05

transform

Move & scale.

06

At-rule

Not property.

Introduction

The @keyframes at-rule in CSS defines how an animation progresses over time. Each keyframe is a snapshot of styles at a specific moment on the timeline. The browser smoothly interpolates between those snapshots to create motion and visual change.

Definition and Usage

@keyframes is not a CSS property — it is an at-rule, like @media or @font-face. It only defines an animation. To run it, you must apply the animation property (or its longhand parts like animation-name and animation-duration) on an element.

The name you give your @keyframes block must match the animation-name you use on the element. For example, @keyframes fadeIn pairs with animation: fadeIn 1s;.

💡
Beginner Tip

Think of @keyframes as a recipe and animation as the instruction to cook it. The recipe lists steps; the animation property tells the browser when to start, how long to run, and whether to repeat.

📝 Syntax

The simplest form uses from and to for the start and end states:

syntax-from-to.css
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Use percentage values when you need steps in between:

syntax-percent.css
@keyframes bounce {
  0% { transform: translateY(0); }
  50% { transform: translateY(-20px); }
  100% { transform: translateY(0); }
}

Apply the animation to an element:

apply-animation.css
.box {
  animation: fadeIn 1s ease-out forwards;
}

Keyframe Selectors

SelectorMeaning
fromStart of the animation (same as 0%)
toEnd of the animation (same as 100%)
0%, 50%, 100%Specific points along the timeline
Animation nameCustom identifier referenced by animation-name
@keyframes name { } from = 0% to = 100%

Animation Shorthand Parts

  • animation-name — Must match the @keyframes name.
  • animation-duration — How long one cycle takes (e.g. 2s, 500ms).
  • animation-timing-function — Speed curve: ease, linear, ease-in-out.
  • animation-iteration-count1, infinite, or a number.
  • animation-fill-modeforwards keeps the final state after the animation ends.

⚡ Quick Reference

QuestionAnswer
TypeAt-rule (not a CSS property)
Basic syntax@keyframes name { from { } to { } }
Timeline0% start, 100% end
Apply animationanimation: name 2s ease infinite;
Best performanceAnimate transform and opacity
AccessibilityRespect prefers-reduced-motion
Browser supportUniversal in all modern browsers

When to Use @keyframes

Reach for @keyframes when you need motion or change over time:

  • Loading indicators — Spinners, pulses, and skeleton screens.
  • Micro-interactions — Button hover effects, icon bounces, notification badges.
  • Entrance effects — Fade-in cards, slide-up modals, reveal on scroll.
  • Attention cues — Gentle highlights that draw the eye without being distracting.
  • Decorative motion — Background gradients, floating shapes, hero animations.

For instant state changes with no intermediate steps, transition is simpler. Use @keyframes when you need multi-step or repeating animations.

👀 Live Preview

See keyframe animations in action — pulse, slide, and timeline steps:

Pulse (0% → 50% → 100%)
Slide (from → to)
Timeline 0% start → 50% midpoint → 100% end

Examples Gallery

Practice @keyframes with from/to animations, percentage steps, transform motion, and the animation shorthand.

🔠 Core Patterns

Start with simple from/to keyframes, then add percentage steps.

Example 1 — Basic from/to Animation

Define start and end states with from and to, then loop the animation.

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

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

How It Works

from sets the starting color. to sets the ending color. infinite alternate plays the animation back and forth forever.

Example 2 — Percentage Keyframes

Add a midpoint at 50% to create a pulse effect with scale and opacity.

keyframes-percent.css
@keyframes pulse {
  0% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.15); opacity: 0.7; }
  100% { transform: scale(1); opacity: 1; }
}

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

How It Works

Percentages mark positions on the timeline. The browser interpolates smoothly between 0%, 50%, and 100%.

🎨 Motion & Shorthand

Animate movement with transform and connect keyframes via the animation shorthand.

Example 3 — Transform Animation

Move an element horizontally using translateX in keyframes.

keyframes-transform.css
@keyframes slideRight {
  from { transform: translateX(0); }
  to { transform: translateX(120px); }
}

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

How It Works

transform animations run on the GPU and perform better than animating left or margin.

Example 4 — Animation Shorthand

Use the animation shorthand with forwards so the element stays at its final state.

keyframes-shorthand.css
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  animation: fadeIn 0.8s ease-out forwards;
}
Try It Yourself

How It Works

forwards keeps the to styles after the animation finishes instead of reverting to the element’s original styles.

💬 Usage Tips

  • Match names exactly@keyframes fadeIn requires animation-name: fadeIn.
  • Prefer transform + opacity — Smoothest performance for most animations.
  • Use alternateanimation-direction: alternate reverses on each cycle.
  • Keep durations short — UI animations often work best between 200ms and 1s.
  • Test reduced motion — Wrap animations in @media (prefers-reduced-motion: no-preference).

⚠️ Common Pitfalls

  • Name mismatch — A typo in the animation name means nothing runs.
  • Forgetting animation property@keyframes alone does nothing without animation.
  • Animating layout propertieswidth, height, and margin can cause jank.
  • Too many infinite loops — Constant motion distracts users and drains battery.
  • Confusing with transitiontransition handles A-to-B on hover; @keyframes handles multi-step timelines.

♿ Accessibility

  • prefers-reduced-motion — Disable or simplify animations for users who request reduced motion.
  • No essential information in motion — Do not hide content that only appears during an animation.
  • Avoid seizure triggers — No rapid flashing (more than 3 flashes per second).
  • Pause decorative loops — Consider letting users stop infinite animations.
  • aria-hidden on decorative motion — Purely visual animations should not confuse screen readers.

🧠 How @keyframes Works

1

@keyframes defines steps

You name the animation and set styles at from, to, or percentage points.

Define
2

animation property triggers it

An element with animation: name duration starts the timeline.

Trigger
3

Browser interpolates

Styles blend smoothly between keyframes based on the timing function.

Interpolate
=

Animated element

The element moves, fades, or changes over the defined duration.

🖥 Browser Compatibility

The @keyframes at-rule and CSS animations have universal support in all modern browsers including Chrome, Firefox, Safari, Edge, and Opera.

Baseline · Universal support

@keyframes + CSS animations

Keyframe animations work in every major browser without vendor prefixes in current versions.

100% @keyframes rule
Google Chrome All modern versions
Full support
Mozilla Firefox All modern versions
Full support
Apple Safari All modern versions
Full support
Microsoft Edge All modern versions
Full support
Opera All modern versions
Full support
@keyframes at-rule 100% supported

Bottom line: @keyframes is safe for production. Pair with prefers-reduced-motion for accessible animations.

🎉 Conclusion

The @keyframes at-rule lets you build rich CSS animations by defining style changes at specific timeline points. Combine it with the animation property to control duration, timing, repetition, and fill behavior.

Start with simple from/to animations, add percentage steps when needed, and prefer transform and opacity for smooth performance. Always consider users who prefer reduced motion.

💡 Best Practices

✅ Do

  • Match @keyframes name to animation-name
  • Animate transform and opacity for performance
  • Use prefers-reduced-motion media query
  • Keep UI animation durations under 1 second
  • Use forwards when the final state should persist

❌ Don’t

  • Define keyframes without applying animation
  • Run infinite loops on large page sections
  • Animate layout properties when transform works
  • Flash content more than 3 times per second
  • Confuse @keyframes with transition

Key Takeaways

Knowledge Unlocked

Five things to remember about @keyframes

Use these points when building CSS animations.

5
Core concepts
0% 02

Timeline

from to 100%.

Syntax
anim 03

animation

Runs it.

Apply
tx 04

transform

Best motion.

Perf
a11y 05

Reduced

Motion respect.

A11y

❓ Frequently Asked Questions

The @keyframes at-rule defines the steps of a CSS animation. You give it a name and describe how styles change at different points in time — then connect that name to an element using the animation property.
First define @keyframes myAnim { ... }, then apply it: animation: myAnim 2s ease-in-out infinite;. The animation-name must match the @keyframes name exactly.
from is the same as 0% (start) and to is the same as 100% (end). Use percentages when you need intermediate steps like 25%, 50%, or 75% along the timeline.
Properties that can change smoothly over time work best: opacity, transform, color, background-color, width, height, and more. Avoid animating layout-heavy properties like margin when transform performs better.
Yes. @keyframes and CSS animations are supported in all modern browsers including Chrome, Firefox, Safari, Edge, and Opera. Always respect prefers-reduced-motion for accessibility.

Practice in the Live Editor

Open the HTML editor, write an @keyframes block, and connect it with animation on an element.

HTML Editor →

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