1. Web Design
  2. CSS Animation

A Beginner’s Introduction to CSS Animation

Scroll to top
Read Time: 7 mins

Nowadays, more and more websites are using animations, whether that be in the form of GIFs, SVGs, WebGL, background videos and so on. When used properly, animation on the web brings life and interactivity, adding an extra layer of feedback and experience for users.

In this tutorial I am going to introduce you to CSS animations; a highly performant way of doing things which is becoming more and more popular as browser support improves. Having covered the basics, we're going to build a quick example which will animate a square element into a circle:

Premium Options

The designers on Envato Market have been busy creating a range of CSS animations for you to plug in to your websites, from shadows to ribbons, sliders, and more.

CSS3 Shadow Pack on Envato MarketCSS3 Shadow Pack on Envato MarketCSS3 Shadow Pack on Envato Market
CSS3 Shadow Pack on Envato Market

An Introduction to @keyframes and Animation

The main component of CSS animations is @keyframes, the CSS rule where animation is created. Think of @keyframes as being stages along a timeline. Inside @keyframes, you can define these stages, each having a different style declaration.

Next, to make CSS animations work, you need to bind the @keyframes to a selector. This will gradually parse all the code inside the @keyframes declarations and change the initial style to the new style, based on the stages.

The @keyframes

Here we'll set the animation stages. Our @keyframes properties are:

  • A name of our choosing (tutsFade in this case).
  • Stages: 0%-100%; from (equal to 0%) and to (equal to 100%).
  • CSS styles: the style that you would like to apply for each stage.

For example:


or the shorthand:

The code above will apply a transition to the opacity of an element, from opacity: 1 to opacity: 0. Each of the approaches above will achieve the same end result.

The Animation

The animation property is used to call @keyframes inside a CSS selector. Animation can have multiple properties:

  • animation-name: @keyframes name (remember we chose tutsFade).
  • animation-duration: the timeframe length, the total duration of the animation from start to the end.
  • animation-timing-function: sets the animation speed ( linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier ).
  • animation-delay: the delay before our animation will start.
  • animation-iteration-count: how many times it will iterate through animation.
  • animation-direction: gives you the ability to change the loop direction, from start to end ,or from end to start, or both.
  • animation-fill-mode: specifies which styles will be applied to the element when our animation is finished ( none | forwards | backwards | both )

For example:

or shorthand:

The code above will create a blinking effect, with a 1 second animation delay, a 4 second total animation duration, with alternate direction and infinite linear loop iterations.

Adding Vendor Prefixes

Whilst a working draft, we need to use browser-specific prefixes to ensure the best browser support possible. The standard prefixes apply:

  • Chrome & Safari: -webkit-
  • Firefox: -moz-
  • Opera: -o-
  • Internet Explorer: -ms-

An animation property using vendor prefixes will look like: 

alongside with @keyframes:

For the sake of readability during this tutorial I will continue further without using prefixes, but the final version will include them and I would like to encourage you to use them in your CSS code.

To find out more about vendor prefixes, you can check, which is a great website for vendor prefixes resources.

Multiple Animations

You can add multiple animations using a comma separator. Let’s say that we want to add an additional rotation to our tutsFade element, we'd do so by declaring extra @keyframes and then binding them to our element:

Square to Circle Tutorial

Let’s jump in and create a simple shape transition; a square to circle animation using the above principles. We will have five stages in total and for each stage we will define a border-radius, a rotation and a different background color to our element. Enough talking, let’s jump into coding.

Basic Element

First, let’s create the markup, an element to animate. We're not even going to bother with class names, we're just going to use a plain div for now:

Then, using an element selector (div {}), add default styling to the div:

Declaring the Keyframes

Now let’s prepare @keyframes, which we'll call square-to-circle, and the five stages

We need to define some styes within these stages, so let's begin by dictating the border-radius for each corner of the square:

Additionally we can declare a different background-color for each stage.

To really hit the idea home, let's go beyond border-radius and background-color by rotating the div and adding a little visual interest.

Apply the Animation

Having defined our square-to-circle animation, we need to apply it to the div:

Here you see we've added a shorthand animation property, which states:

  • The animation-name is square-to-circle.
  • The animation-duration is 2s.
  • The animation-delay is 1s.
  • The animation-iteration-count is infinite, so it will carry on indefinitely.
  • And the animation-direction is alternate, so it will play from beginning to end, then back to the beginning, then again to the end, and so on. 

Use Timing-Function Awesomeness 

One last value we can add to the animation property is the animation-timing-function. This will define the speed, acceleration and deceleration of our movement. This function can be a very detailed value, which is awkward to calculate manually, but there are a lot of free websites which provide resources and live customisation for animation timing functions.

One such tool is the CSS Easing Animation Tool, so let's use that to calculate our timing function.

I would like to add an elastic effect to our square-to-circle animation, using a cubic-bezier function.

Having played around with the handles and generated some kind of bezier curve, update the animation timing-function value using the snippet provided.

The final code, without using vendor prefixes ( -webkit- , -moz-, -ms-, -o- ) is as follows:

One Last Thing

All works well in modern browsers, but Firefox has a nasty habit of rendering transforming objects poorly. Take a look at these jagged lines to see what I mean:

Luckily, there's a workaround for this. Add the following transparent outline to your div and Firefox will render things perfectly!


That's it! We've used CSS Animation syntax to create a simple, repeating animation.

Browser Support

For up-to-date information on the browsers support for CSS animation, check out Can I use.. but in a nutshell, supporting browsers include: Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+.


Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.