W3docs

CSS @keyframes Rule

The @keyframes rule specifies the animation code. The animation is created by gradually changing from one set of CSS styles to another.

The @keyframes at-rule is the basis for keyframe animations used to animate (gradually change from one style to another) many CSS properties. This rule allows specifying what should happen at specific moments during the animation by defining styles for keyframes (or waypoints) along the animation sequence.

The @keyframes rule is a core part of the CSS Animations specification.

The @keyframes rule and its identifier are followed by rule sets (i.e. style rules with selectors and declaration blocks, as in normal CSS code) delimited by curly braces.

Keyframes in the animation sequence

Inside the curly braces, keyframe selectors define when styles should change during the animation sequence. The set of CSS styles can be updated multiple times throughout the animation.

Keyframe selector

The keyframe declaration block includes CSS properties and their values. A keyframe selector can use a percentage (%) or the keywords from (equivalent to 0%) and to (equivalent to 100%). 0% marks the start of the animation, and 100% marks the end.

You are not limited to two keyframes. Adding intermediate selectors such as 25% or 75% lets you control the animation at as many points as you need:

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

You can also group selectors that share the same styles, separating them with commas: 0%, 100% { opacity: 1; }.

How the browser fills in the gaps

You only declare styles at the keyframe waypoints — the browser interpolates every frame in between. If you animate background-color from green at 0% to blue at 50%, the colors blend smoothly across that interval; you never have to specify the intermediate values yourself.

A few rules govern this in-betweening:

  • Only animatable properties interpolate. Numeric and color values (such as width, opacity, transform, and color) animate smoothly. Properties like display jump instantly between keyframes rather than tweening.
  • The pacing is controlled separately. The shape of the interpolation curve (linear, ease, ease-in-out, etc.) comes from animation-timing-function, not from @keyframes.
  • Missing from/to are inferred. If you omit the 0% or 100% keyframe, the browser uses the element's existing computed value for that property as the missing endpoint.

Vendor prefixes

The @keyframes rule is fully supported by all modern browsers without the need for vendor prefixes. Legacy prefixes (like -webkit- or -moz-) are no longer required.

Syntax

Syntax of the CSS @keyframes at-rule

@keyframes animationname {keyframes-selector {css-styles;}}

Using @keyframes as a keyword

The @keyframes rule consists of the @keyframes keyword followed by an identifier (chosen by the developer) that defines the animation. To bind the animation to an element, this identifier is used as the value for the animation-name property.

This is what it looks like:

How to define animation and apply it to an element

/* define the animation */
@keyframes your-animation-name {
  /* style rules */
}

/* apply it to an element */
.element {
  animation-name: your-animation-name;
  /* OR using the animation shorthand property */
  animation: your-animation-name 1s …;
}

Example of the @keyframes rule with the background-color property:

Example of CSS @keyframes at-rule

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .element {
        padding: 50px;
        animation: backgrounds 4s infinite;
      }
      @keyframes backgrounds {
        0% {
          background-color: #8ebf42;
        }
        50% {
          background-color: #1c87c9;
        }
        100% {
          background-color: #cccccc;
        }
      }
    </style>
  </head>
  <body>
    <h2>@keyframes example</h2>
    <div class="element">The background of this text is animated.</div>
  </body>
</html>

In this example, we animate the background-color property. First, we set an identifier for the animation: backgrounds. Then we set keyframe selectors (0%, 50%, and 100%) and define values for the property: green, blue, and grey. This means that at the starting point (0%), the background color will be light green until it reaches the next keyframe (50%). In the middle of the animation sequence, the background will turn to light blue, and at the endpoint (100%), it will be grey.

Example of the @keyframes rule:

Example of CSS @keyframes at-rule with infinite value

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      div {
        width: 10px;
        height: 100px;
        background: red;
        border-radius: 50%;
        position: relative;
        animation: element 4s infinite;
      }
      @keyframes element {
        0% {
          top: 0px;
          background: #1c87c9;
          width: 100px;
        }
        100% {
          top: 200px;
          background: #8ebf42;
          width: 150px;
        }
      }
    </style>
  </head>
  <body>
    <h2>@keyframes rule example</h2>
    <div></div>
  </body>
</html>

Example of using the @keyframes rule to make a falling image:

Example of CSS @keyframes at-rule with the transform property

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      html,
      body {
        height: 90%;
      }
      .container {
        margin: 30px auto;
        min-width: 320px;
        max-width: 600px;
        height: 90%;
        overflow: hidden;
      }
      img {
        transform-origin: left center;
        animation: fall 5s infinite;
      }
      @keyframes fall {
        from {
          transform: rotate(0) translateX(0);
          opacity: 1;
        }
        to {
          transform: rotate(90deg) translateX(200px);
          opacity: 0.1;
        }
      }
    </style>
  </head>
  <body>
    <h2>@keyframes example</h2>
    <div class="container">
      <img src="https://api.w3docs.com/uploads/media/default/0001/01/0710cad7a1017902166203def268a0df2a5fd545.png" alt="W3docs" width="150" height="50" />
    </div>
  </body>
</html>

Syntax Components

ComponentDescription
identifierSpecifies the name of the animation. Required.
keyframe-selectorSpecifies the percentage of the animation duration. Accepts 0% to 100%, from (0%), or to (100%). Required.
declaration-blockContains the CSS properties and values to apply at each keyframe. Required.

Common gotchas

  • @keyframes alone does nothing. The rule only defines the animation. Nothing moves until you reference the name from an element with the animation-name property (or the animation shorthand) and give it a non-zero animation-duration.
  • Names are case-sensitive and must not be a CSS-wide keyword. Avoid reserved words like none, initial, inherit, and unset as animation names.
  • Duplicate keyframe rules cascade. If two @keyframes blocks share the same name, the last one defined wins entirely — they are not merged.
  • !important inside a keyframe is ignored. The Animations spec specifically drops !important declarations within keyframes.

Practice

Practice
What is correct about CSS keyframes?
What is correct about CSS keyframes?
Was this page helpful?