CSS Animations

There are two ways to animate things with CSS. One is with the transition property. The other way is by creating a keyframe animation and the animation property. This video and article are referring to the Keyframe Animation method.

See the Pen CSS Animations by Lisa (@lisa_c) on CodePen.

Preferred Learning Method?

Code Snippets
If you just want the code and don’t need a description.

Watching a Video
If you like being shown how something works with some explanation watch the video.

Reading a description
If you learn better by reading, I am including the transcript of the video with corresponding code snippets embedded.

More Info


There is a lot of discussion around what is better to use for animations – CSS or Javascript. I don’t really have the answer to that. Animations are a complex topic and in general you may need to factor in the type of animation you are creating, who your audience is, and what devices the site is viewed on, etc. If you want to read more about performance, you can try this article: High Performance Animations or this one: Myth Busting Mythbusted

Browser Support

CSS Animations work in IE 10 and above. They also work in all other modern desktop browsers. On mobile devices they work in everything except Opera Mini. See caniuse.com for specifics. If it is important that your animation works in earlier versions of IE, you may still want to use Javascript for your animations.


See the Pen CSS Animations by Lisa (@lisa_c) on CodePen.

See the Pen CSS Animations by Lisa (@lisa_c) on CodePen.



Creating CSS Animations can be a lot of fun. The possibilities of things you can do are just about endless. That’s because of the wide range of options that are available, and the ability to use multiple animations at the same time.

Let’s start by displaying an object. I have a simple page with a single circle displayed on the screen.

.circle {
  width: 200px;
  height: 200px;
  border-radius: 100px;
  background-color: #eef529;
  position: absolute;
  top: 0;
  left: 0;

We can create a simple animation to have it fade in and out. I’m going to just stick to using the -webkit prefix here, but obviously you would need to use all of the browser prefixes to get this to work in all browsers. I will include all the prefixes in my final snippet that you can find on the CSS Snippets website.

You define the keyframe with @keyframes statement. You add the prefix after the @ sign. So we need @-webkit-keyframes for webkit browsers.

After that you need to give your animation a name. I’ll call mine fadeInOut. Then we need curly brackets to contain the keyframes.

All animations need at least 2 keyframes. One to define the starting state, and one to define the ending state. The timing of the keyframes is defined with percentages. It starts at 0% and ends at 100%. You can have additional keyframes in between, but it is not necessary.

So at 0%, we can say we have an opacity of 1, and at 100% we have an opacity of 0. Each set of keyframes needs it own curly-brackets to contain the properties you are setting.

/* fadeInOut */
@-webkit-keyframes fadeInOut {
  from { opacity: 1; }
  to   { opacity: 0; }

The second step is to call the animation. When you use the animation you need to define two properties. The name, which we defined above, and the duration of the animation.

There are many more properties you can add, but this is the bare minimum. I am using the shorthand format here.

I really prefer to use the shorthand because with all the vendor prefixes that are needed, spelling out all the different properties could become very tedious.

.circle {
  -webkit-animation: fadeInOut 2s;

If I restart the page, we can see the circle fades out once and then remains in view. This is because the default is to only animate one time. If we want the animation to repeat we can add either a number, for the number of times it should repeat, or the word infinite to repeat endlessly.

Now I called this animation fadeInOut but it really isn’t fading in and out. If fades out, then immediately becomes visible again.

There are two ways we can make this fade in as well as fade out.

The easiest say would be to add the animation-direction property and set it to alternate. Normally an animation will just play forward and then start over. But if we say alternate it will go forward and then backwards, and then repeat.

Another way is to add more keyframes and specify exactly when it should fade-in and when it should fade out. You have more control over the timing this way.

I could say I want it to fade out by 30%. Then I’ll keep it hidden for the next 20%, so until 50%. And finally, I’ll bring it back up to full opacity at 100%. I’ll take out the alternate as well. Now it is fading in and out but staying hidden for a moment before it fades back in.

Going back to our simple fadeInOut animation, I want to point out that there is shorthand for 0% and 100%, and that is the words, from and to. That really isn’t shorter, but it is easier to type, so it can be useful for 2 keyframe animations.

You can animate more than one css property at once. Let’s create another animation called shrinkGrow that changes the width and the height during each keyframe.

So I can change the code to use this animation instead.

@-webkit-keyframes shrinkGrow {
  from { width: 200px; height: 200px; }
  to   { width: 100px; height: 100px; }

Another property of animation is the timing-function, which tells the animation how it should accelerate. The default of this is ease. You can see that it is not shrinking and growing in a linear fashion. We can see the difference if we add the word linear to our animation statement.

It is now growing and shrinking at a perfectly even rate. But if we take that out, there is ease happening and it almost appears to bounce a bit. Ease speeds up at the beginning and the end and is slower in the middle. You can also use ease-in or ease-out to only accelerate at the beginning or end. In general, easing makes the animation feel more natural, but sometimes linear is useful.

I’ll add a 3rd animation called move that will move the circle around the screen. I’m going to paste this one in.

@-webkit-keyframes move {
  0%     { left: 0px;   top: 0px; }
  25%    { left: 300px; top: 0px; }
  50%    { left: 300px; top: 300px; }
  75%    { left: 0px;   top: 300px; }
  100%   { left: 0px;   top: 0px}

It just changes the position of the circle.

With alternate on, we can see the easing even better now. I could remove the alternating so it just repeats endlessly in the same direction.

It looks like Brackets isn’t picking up the change so I need to refresh this.

It is possible to use multiple animations on one item and to list them separated by commas. Each animation can have it’s own set of properties.

I’ll make the shrinkgrow linear and have it alternate. It is taking 2 rounds of movement for the circle to get back to it’s original size. That is because this animation is actually taking 4 seconds since it is ‘alternating’. If I change it to 1 seconds it will take only one revolution.

The ability to combine animations is nice because it allows you to keep your code simpler and more modularized with each type of animation discrete. You can use these smaller setups as building blocks to build more complex animations.

I’ll add one more animation called change that alters the colors. I’ll just paste this in, and then add a 3rd animation to circle.

/* change colors */
@-webkit-keyframes change {
  0%      { background-color: #eef529; }
  16.67%  { background-color: #cc5e00; }
  33.33%  { background-color: #b40808; }
  50%     { background-color: #8312c9; }
  66.67%  { background-color: #1e3cba; }
  83.33%  { background-color: #1ba340; }
  100%    { background-color: #eef529; }

One final property I want to mention is the delay property.

I can delay everything by typing -webkit-animation-delay on a separate line. It will then wait 3 seconds to start the animation.

If you use the shorthand, the delay must be the second time displayed. The first time in the shorthand must be the duration.
If I delay the color change by 2 seconds you can see that it doesn’t start changing colors until after 1 full rotation.

So this was an almost complete look at how CSS animations work. There are a few more details on some of the animation properties that you might want to explore. I would encourage you to read the MDN reference on animations which gives a very clear explanation of all of the properties and how they work.

Leave a Reply

Your email address will not be published. Required fields are marked *