Skip to main content
Syllabus
On this page

CSS Keyframe Animations: @keyframes, animation shorthand, fill-mode and @property

Badar KhalilUpdated September 30, 2026 5 min read

What are CSS keyframe animations?

CSS keyframe animations let you define a sequence of styles using @keyframes and then apply it to an element with the animation property. Unlike transitions, animations can run automatically on load, loop forever, have many steps, play in reverse and be paused. They power loaders, attention effects, skeleton screens, hero intros and looping backgrounds without any JavaScript.

Focus keyword: CSS keyframe animations. Related trending keywords: @keyframes animation, animation-fill-mode, CSS loading spinner, staggered animation, @property animated gradient, animation-composition, CSS typing effect.

Step 1: define @keyframes

Give the animation a name and describe the states. Use from and to for two steps, or percentages for multiple steps: @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.15); } 100% { transform: scale(1); } }. If you omit a from keyframe, the browser uses the element's current style.

Step 2: apply it with animation

The longhand properties are:

  • animation-name: which @keyframes to use.
  • animation-duration: length of one cycle.
  • animation-timing-function: easing for the whole cycle (and it can be overridden per keyframe).
  • animation-delay: wait before starting. Negative values start part-way through, useful for staggering loops.
  • animation-iteration-count: a number or infinite.
  • animation-direction: normal, reverse, alternate, alternate-reverse.
  • animation-fill-mode: none, forwards, backwards, both. Use both (or forwards) to keep the end state, and backwards to apply the first keyframe during the delay.
  • animation-play-state: running or paused.
  • animation-composition: replace, add or accumulate, which controls how animated values combine with the element's underlying values.

Shorthand: animation: pulse 1.5s ease-in-out 0s infinite alternate both;. Tip: the first time value is always the duration and the second is the delay.

Transitions vs animations

  • Transition: reacts to a state change, has only a start and an end, no looping.
  • Animation: can start by itself, has many keyframes, can loop, reverse and pause.

Multiple animations on one element

Separate with commas: animation: fadeIn .6s ease-out both, float 3s ease-in-out .6s infinite alternate;. Be careful that two animations do not fight over the same property, such as two that both animate transform. The later one wins. Use individual properties (translate, rotate, scale) or animation-composition: add to combine them.

steps() for frame-by-frame effects

Use steps(n) as the timing function for sprite sheets, typing effects and blinking cursors. It jumps between values instead of interpolating smoothly.

Stagger with custom properties

Set an index per element, such as style='--i: 3', and use animation-delay: calc(var(--i) * 100ms). This is a clean way to reveal lists, cards and menus one after another.

Animating gradients with @property

Normal custom properties are not animatable because the browser does not know their type. Registering them with @property (for example, syntax: '<angle>') makes them interpolable, which enables rotating gradients, animated borders and color shifts.

Best practices

  • Animate transform and opacity whenever possible for smooth 60fps or higher.
  • Use animation-fill-mode: both for entry animations so there is no flash of the un-animated state.
  • Keep looping animations subtle, and always offer a way to reduce or stop them.
  • Use meaningful names like fade-slide-up instead of anim1.
  • Do not animate everything at once. Motion should guide attention.

Quick summary

Define with @keyframes, apply with animation, and control the behavior with fill-mode, direction, iteration count and delays. Use CSS keyframe animations for automatic, multi-step or looping motion.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Exercise: Create a fade-slide-in entry animationHTML

Write @keyframes named fade-slide-in that animates opacity from 0 to 1 and translateY from 30px to 0. Apply it to .hero with a duration of 700ms, ease-out and fill-mode both. Then make the h1 and p animate one after another using an --i custom property and animation-delay.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
The heading fades and slides up first, followed by the paragraph 120ms to 200ms later, and both stay visible at the end.

This is a self-check — compare your result with the expected output above.

Was this page helpful?