Syntax
@keyframes name { 0% { } 100% { } }
animation: name duration timing-function iteration-count;Examples
A Basic Keyframe Animation
Defining and applying a fade-in-and-rise animation.
/* Demo setup: sizing, structure or neutral surfaces. */
.preview-animation{padding:1.5rem;background:#dcfce7;color:#14532d;border:1px solid #16a34a}.loading-dot{display:inline-block;width:2rem;height:2rem;background:#c2410c;border-radius:50%;margin:2rem}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.card {
animation: fadeInUp 0.5s ease-out;
}- The target element matches the animation selector, so keyframes are applied to something visible.
- Run the example again to replay the entrance animation from its start.
- For production motion, respect reduced-motion preferences and avoid using motion as the only status information.
HTML used by this example
<div class="card preview-animation">A newly revealed lesson</div>Multi-Step and Looping Animation
A pulsing loading indicator using percentage-based keyframes.
/* Demo setup: sizing, structure or neutral surfaces. */
.preview-animation{padding:1.5rem;background:#dcfce7;color:#14532d;border:1px solid #16a34a}.loading-dot{display:inline-block;width:2rem;height:2rem;background:#c2410c;border-radius:50%;margin:2rem}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.1); }
}
.loading-dot {
animation: pulse 1.5s ease-in-out infinite;
}- The target element matches the animation selector, so keyframes are applied to something visible.
- The dot repeats its opacity and scale changes through the defined keyframe stops.
- For production motion, respect reduced-motion preferences and avoid using motion as the only status information.
HTML used by this example
<span class="loading-dot" role="img" aria-label="Decorative pulsing status dot"></span><p>This is a visual animation demo, not a real loading request.</p>Parameters and values
- animation-name (identifier): References a @keyframes rule by name
- animation-duration (time): Length of one animation cycle
- animation-iteration-count (number | infinite): How many times the animation repeats
- animation-fill-mode (none | forwards | backwards | both): What styles apply before/after the animation runs
Best practices
- Use @keyframes for multi-step or looping animations, and simple transitions for animating between exactly two states
- Set animation-fill-mode: forwards when the animation's end state should persist after it finishes, rather than snapping back to the original style
- Use infinite only for genuinely continuous effects like loading spinners - most UI animations should run once
- Wrap non-essential animations in an @media (prefers-reduced-motion: no-preference) query so users with motion sensitivity are not affected
Browser compatibility
- chrome
- Yes
- firefox
- Yes
- safari
- Yes
- edge
- Yes
These are the existing reference’s support labels, not tested minimum versions. Individual values and APIs can have different support. Check the linked specification before choosing a browser target.
CSS specifications (modules)