Keyframe Animations

CSS keyframe animations use an @keyframes rule to define styles at multiple points along a timeline, letting an element loop through multi-step motion automatically without any JavaScript.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

If CSS transitions are like a dimmer switch (smooth A → B), keyframe animations are like a choreographed dance routine — you define every step: "at 0% do this, at 50% do that, at 100% finish here." You control the entire performance, not just the start and end.

Transitions only animate between two states (A → B). Keyframe animations let you define an unlimited number of intermediate states at specific percentages (0%, 25%, 50%, 75%, 100%). This makes complex, multi-step sequences possible — things like bouncing, morphing, color cycling, and loading indicators.

A keyframe animation has two parts: the @keyframes rule (which defines the steps) and the animation property (which applies it to an element). Unlike transitions, animations can run automatically on page load — no hover or click required. They can also loop infinitely, alternate direction, and be paused/resumed.

Performance remains critical: The same GPU-optimized properties apply — animate transform and opacity for butter-smooth 60fps. Animating width , height , or top causes layout thrashing and janky performance, especially on mobile.

The four most common animation patterns are bounce (vertical movement), pulse (scale in/out), spin (continuous rotation), and fade-in (opacity + position). Each uses @keyframes with different percentage stops. The fade card uses animation-fill-mode: both to stay visible after the animation ends.

animation-delay combined with :nth-child() creates staggered entrances where items slide in one after another. You can also trigger animations on hover (useful for attention effects) and pause infinite animations using animation-play-state: paused — perfect for tickers and carousels.

Multi-step keyframes (0%, 25%, 50%, 75%, 100%) create complex sequences. The color morph cycles through five colors while changing border-radius. The skeleton loader uses a gradient shimmer — a production-quality loading indicator used by Facebook, YouTube, and most modern apps. The typing effect combines steps() timing with a blinking cursor.

Some users experience motion sickness, vertigo, or distraction from animations. The @media (prefers-reduced-motion: reduce) query lets you disable or simplify animations for users who've enabled "Reduce motion" in their OS settings. This isn't optional — it's a core accessibility requirement.

Practice quiz

Which CSS rule defines the steps of a keyframe animation?

  • @animation
  • @keyframes
  • @motion
  • @steps

Answer: @keyframes. The @keyframes rule defines styles at points along the timeline; the animation property then applies it to an element.

Inside @keyframes, which keyword pair is equivalent to 0% and 100%?

  • start and stop
  • begin and end
  • from and to
  • open and close

Answer: from and to. from is 0% and to is 100%, useful for simple two-state animations.

Which property makes an animation repeat forever?

  • animation-repeat: forever
  • animation-iteration-count: infinite
  • animation-loop: true
  • animation-count: all

Answer: animation-iteration-count: infinite. animation-iteration-count: infinite loops the animation endlessly; its default is 1.

Which value of animation-fill-mode keeps the element’s final keyframe state after the animation ends?

  • none
  • backwards
  • forwards
  • reset

Answer: forwards. forwards retains the last keyframe; both also applies the first keyframe during any delay.

How do you create a staggered entrance where items animate one after another?

  • Different animation-duration per item
  • Different animation-delay per item (e.g. via :nth-child)
  • Different animation-name per item
  • Different z-index per item

Answer: Different animation-delay per item (e.g. via :nth-child). Giving each item a larger animation-delay (commonly with :nth-child) staggers when each one starts.

Which property pauses or resumes a running animation?

  • animation-state
  • animation-play-state
  • animation-pause
  • animation-control

Answer: animation-play-state. animation-play-state: paused freezes the animation; running resumes it — handy for tickers on hover.

For smooth 60fps animation, which properties are best to animate?

  • width and height
  • top and left
  • transform and opacity
  • margin and padding

Answer: transform and opacity. transform and opacity are GPU-accelerated and skip layout; animating width/height/top causes reflow and jank.

Which timing function creates a typewriter / frame-by-frame effect?

  • ease-in-out
  • linear
  • steps(n)
  • cubic-bezier(0,0,1,1)

Answer: steps(n). steps(n) jumps between n discrete frames rather than interpolating smoothly, ideal for typing effects.

Which media query should you honor to disable motion for users who request it?

  • @media (prefers-reduced-motion: reduce)
  • @media (no-animation)
  • @media (motion: off)
  • @media (accessibility: reduce)

Answer: @media (prefers-reduced-motion: reduce). @media (prefers-reduced-motion: reduce) lets you remove or simplify animations for users who enabled Reduce Motion.

In , what does the specify?

  • The delay before starting
  • The duration of one cycle
  • The number of iterations
  • The timing function

Answer: The duration of one cycle. In the animation shorthand the first time value is the duration (animation-duration) of one cycle.