The animation property in CSS can be used to animate many other CSS properties such as color, background-color, height, or width. Each animation needs to be defined with the @keyframes at-rule which is then called with the animation property, like so:

.element {
  animation: pulse 5s infinite;

@keyframes pulse {
  0% {
    background-color: #001F3F;
  100% {
    background-color: #FF4136;

See the Pen A simple animation by CSS-Tricks (@css-tricks) on CodePen.

Each @keyframes at-rule defines what should happen at specific moments during the animation. For example, 0% is the beginning of the animation and 100% is the end. These keyframes can then be controlled either by the shorthand animation property, or its eight sub-properties, to give more control over how those keyframes should be manipulated.


  • animation-name: declares the name of the @keyframes at-rule to manipulate.
  • animation-duration: the length of time it takes for an animation to complete one cycle.
  • animation-timing-function: establishes preset acceleration curves such as ease or linear.
  • animation-delay: the time between the element being loaded and the start of the animation sequence.
  • animation-direction: sets the direction of the animation after the cycle. Its default resets on each cycle.
  • animation-iteration-count: the number of times the animation should be performed.
  • animation-fill-mode: sets which values are applied before/after the animation.
    For example, you can set the last state of the animation to remain on screen, or you can set it to switch back to before when the animation began.
  • animation-play-state: pause/play the animation.

These sub-properties can then be used like so:

@keyframes stretch {
  /* declare animation actions here */

.element {
  animation-name: stretch;
  animation-duration: 1.5s; 
  animation-timing-function: ease-out; 
  animation-delay: 0s;
  animation-direction: alternate;
  animation-iteration-count: infinite;
  animation-fill-mode: none;
  animation-play-state: running; 

  is the same as:

.element {

See the Pen EjaJNd by CSS-Tricks (@css-tricks) on CodePen.

Here's a full list of which values each of these sub-properties can take:

animation-timing-function ease, ease-out, ease-in, ease-in-out, linear, cubic-bezier(x1, y1, x2, y2) (e.g. cubic-bezier(0.5, 0.2, 0.3, 1.0))
animation-duration Xs or Xms
animation-delay Xs or Xms
animation-iteration-count X
animation-fill-mode forwards, backwards, both, none
animation-direction normal, alternate
animation-play-state paused, running, running

Multiple steps

If an animation has the same starting and ending properties, it's useful to comma-separate the 0% and 100% values inside @keyframes:

@keyframes pulse {
  0%, 100% {
    background-color: yellow;
  50% {
    background-color: red;

Multiple animations

You can comma-separate the values to declare multiple animations on a selector as well. In the example below, we want to change the color of the circle in a @keyframe whilst also nudging it from side to side with another.

.element {
    pulse 3s ease infinite alternate, 
    nudge 5s linear infinite alternate;

See the Pen c6d27fda8e1244d44bf04728049d7c1d by CSS-Tricks (@css-tricks) on CodePen.


Animating most properties is a performance concern, so we should proceed with caution before animating any property. However, there are certain combinations that can be animated safely:

  • transform: translate()
  • transform: scale()
  • transform: rotate()
  • opacity

Which properties can be animated?

MDN has a list of CSS properties which can be animated. Animatable properties tend to colors and numbers. An example a non-animatable property is background-image.

More information

Browser support

Chrome Safari Firefox Opera IE Android iOS
6+ 5+ 5+ 12+ 10+ 4.4+ 4+


Although browser support is quite good for this property in modern browsers, we might want to support as many older browsers as we can. In that case we'd need to use vendor prefixes:

.element {
  -webkit-animation: KEYFRAME-NAME 5s infinite;
  -moz-animation:    KEYFRAME-NAME 5s infinite;
  -o-animation:      KEYFRAME-NAME 5s infinite;
  animation:         KEYFRAME-NAME 5s infinite;

@-webkit-keyframes KEYFRAME-NAME {
  0%   { opacity: 0; }
  100% { opacity: 1; }
@-moz-keyframes KEYFRAME-NAME {
  0%   { opacity: 0; }
  100% { opacity: 1; }
@-o-keyframes KEYFRAME-NAME {
  0%   { opacity: 0; }
  100% { opacity: 1; }
@keyframes KEYFRAME-NAME {
  0%   { opacity: 0; }
  100% { opacity: 1; }


  1. User Avatar
    Permalink to comment#


  2. User Avatar
    Permalink to comment#


  3. User Avatar


    as far as I know, Opera has also implemented animations using the -o- -prefix. Maybe this calls for an update?

    Also, using the -webkit- prefix in your examples could possibly promote the bad practice of using -webkit- only. Maybe such examples need to be changed to the prefix-free version instead?

    Best regards,
    Adam Avramov

  4. User Avatar
    Permalink to comment#

    They are definitely great and better than other tutorials! Thanks, Chris!

  5. User Avatar
    Permalink to comment#

    Hi Chris,
    I’m not sure if you’re aware, but @-ms-keyframes has never existed. IE10+ supports the @keyframes property, and < IE9 doesn’t support animation at all.

    • User Avatar
      Chris Coyier
      Permalink to comment#

      I did know that, this was way out of date that way (pre me knowing that I guess). Got it fixed up.

  6. User Avatar
    Permalink to comment#

    hello sir,
    I want to run animation form{left:0}to{left:75px} then i want to stop my content at place left:75px; permanently until i move my mouse out. Is this possible???if yes then how?????? Please help

    • User Avatar
      Permalink to comment#

      May be you have already figured it out, but this introductory video in this link explains what you’re trying to do.

      The introductory video is free so you won’t need to pay for a subscription (assuming you do not have a Lynda subscription).

    • User Avatar

      Use this with your animation–

      -webkit-animation-fill-mode: forwards;

    • User Avatar
      Oliver Otterson
      Permalink to comment#

      Hi I used CSS-Animations for a little Game:

      Just adding elements with jQuery a class with animation, this makes it pretty easy!

    • User Avatar
      Daniel Parsons
      Permalink to comment#

      Another great post! Plenty of food for thought here.

    • User Avatar
      Shubham Arya

      “animation-fill-mode: forwards;”

      By using this, whatever you have in “to” condition will remain there.

    • User Avatar
      Permalink to comment#

      I dumped in the same problem, but studying the css code library I’ve easily found the solution to “stop” then animation to the last color chosen.

      The code has its rules:
      animation-fill-mode REQUIRES the animation-iteration-count to perform the action to allow the “stop in the end” mode.
      So, here is the code to add to make it works and have fun:

      animation-iteration-count: 1;
      -webkit-animation-iteration-count: 1; /* Chrome and Safari /
      animation-fill-mode: forwards;
      -webkit-animation-fill-mode: forwards; /
      Chrome and Safari */

      Code tested in Edge, Safari, Chrome and Mozilla. Maxthon works only if updated ( …or if developers update it -.-” ).

      Have a nice day!

  7. User Avatar
    Alex Safayan
    Permalink to comment#

    I was wondering if there is other options instead of ‘alternate’. Please help!

    Alex Safayan

  8. User Avatar
    Permalink to comment#

    This teachings on animations are amaizing!!

  9. User Avatar

    great article

  10. User Avatar
    Permalink to comment#

    multiline blocks of code in in triple <– two “in”s

  11. User Avatar
    Ben Racicot
    Permalink to comment#

    Any clever ideas on starting an animation like this when doing DOM insertion?

  12. User Avatar
    Permalink to comment#

    Is it required to use “-webkit-” while using animations in chrome. I tried them using “-webkit-” but for each animation i have to write code again this leads to very large sizes of my files that i don’t you can see Any suggestions to minify css animation.????

    • User Avatar
      Permalink to comment#

      Take a look at using something like SASS, along with Compass…

      You could also use postCSS along with Grunt/Gulp to save you some more time.

      Even better, use all of them together, and you’re laughing.

      This won’t shrink the CSS filesize (although Grunt/Gulp can be used to minify your CSS for you, on the fly), the prefixes have to be there for complete support… What it will do is allow you to just write one line of CSS, and have all the vendor prefixes automatically applied for you.

  13. User Avatar
    Permalink to comment#
  14. User Avatar
    Shikha Jaiswal
    Permalink to comment#

    Simple and important css tags for animation. Section Of Sub Properties is best one.

  15. User Avatar
    James Sherry
    Permalink to comment#

    The MDN list of animatable properties seems to have disappeared. :(

  16. User Avatar
    Permalink to comment#

    css animation simple trick knowledge

  17. User Avatar
    Permalink to comment#

    var red = [0, 100, 63];
    var orange = [40, 100, 60];
    var green = [75, 100, 40];
    var blue = [196, 77, 55];
    var purple = [280, 50, 60];

    var myName = “EMMANUEL”;
    letterColors =[orange,red,blue,green,purple]
    if(15 > 5) {
    bubbleShape = “circle”;

    else {
    bubbleShape = “square”;

    drawName(myName, letterColors);

  18. User Avatar
    Eric Strickland
    Permalink to comment#

    Hi Chris, if would can you tell me what CSS animation that is being used in this website? I think it’s a beautiful design!!

  19. User Avatar
    Luis M :D
    Permalink to comment#

    Wow, Amazing tricks, Thank you very much! Everything well explained!

Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.