A Simple CSS Animation Tutorial

Let’s turn a yellow square box into a teal circle. (follow me on Twitter.)

Here’s a list of my best web development tutorials.

Complete CSS flex tutorial on Hashnode.

Ultimate CSS grid tutorial on Hashnode.

Higher-order functions .map, .filter & .reduce on Hashnode.

Follow me @ Twitter, Instagram & fb to never miss premium articles.

These diagrams are from CSS Visual Dictionary – grab a copy here.

Check out the above figure. Soon as .animateClass is assigned to an element, animation will start playing. The class has a link to animationName. It must match the name specified by @keyframes rule. This animation is set to last 3 seconds or 3000ms as specified.

Note: Easing adds flavor to your animation — by providing a curve describing relative velocity of your animation at a particular spot on the time line.

We’ll cover easing and all other CSS animation properties throughout the remainder of this article, based on this simple example.

So How Does It Work?

You can animate any CSS property whose physical position, dimensions, angle or color can be changed. Basic animation is surprisingly simple to implement using keyframes.

CSS animation keyframes are specified using the @keyframes directive. A keyframe is simply the element’s state at a single point on animation time line.

CSS animation engine will automatically interpolate between animation keyframes. All you need to do is specify the state of CSS properties at the start and end points of the animation.

Once all of our keyframe locations are set up (which are often specified in percentages) all we need to do is set up the defaults for our original element we wish to animate.

Then create a named animation using @keyframes animationName {…} format, that stores all the keyframes. We’ll take a look at that in just a moment!

Finally, create a special class that will define your animation’s duration, direction, repeatability, and easing type… and link it to the same animation name that was used by @keyframes directive. This process is explained visually in the following sections.

CSS Animation Properties

The animation property is the short-hand to the 8 stand-alone animation properties described below:

animation-name — name of the keyframe specified by @keyframes rule.

animation-duration — duration of the animation in milliseconds.

animation-timing-function — specify easing function.

animation-delay — add delay before animation starts playing.

animation-iteration-count — number of times animation should play.

animation-direction — play forwards, backwards or alternate sequence.

animation-fill-mode — state of the animation when it is not playing.

animation-play-state — specify whether animation is running or is paused.

In the following sections we’ll explore each one visually.


The alpha-numeric animation identifier name:

Animation name must refer to the one specified by @keyframes directive:


You usually want to plan the length of your animation first.

As you can see in the above figure, you can specify duration in seconds or milliseconds, if you need more precision. For example 3000ms is the same as 3s and 1500ms is the same as 1.5s

It is also possible to assign a delay in milliseconds before animation starts playing.


You can assign any of the four values to the animation-direction property:

The above figure displays the values normal, reverse, alternate and alternate-reverse and their effects.

CSS animation engine will automatically interpolate between frames. An interpolated animation state is simply any state between any two frames. As the color transitions from yellow to teal, it will gradually change over the period of time specified by the animation property (here, as a short-hand).


Number of times animation will be repeated.

Play animation 1 time (default).
Repeat animation 2 times.
Repeat animation 3 times.

As you can see, the obvious problem here is that the animation will ”jump” back to the first frame again.

You can use some of the other animation properties to make sure that this jumping doesn’t occur. You can design your animation to loop, or tweak other properties based on particular UI dynamics you’re looking for. This way you can design only ”half” of your animation, and tweak properties to play it forwards or backwards, let’s say on mouse-in and mouse-out events.


Easing is specified by animation-timing-function. It adds personality to your animation. This is done by adjusting velocity of the animation at any given point on the time line. Start, Middle and End points are of particular interest. Each easing type is defined by a Bézier curve function.

Animation-timing-function: linear
Animation-timing-function: ease
Animation-timing-function: ease-in
Animation-timing-function: ease-out
Animation-timing-function: ease-in-out
You can create your own cubic Bézier curves.
Two control points P1 and P2 are passed to cubic-bezier function as arguments. The range of values is between 0.0 and 1.0.

Because easing is determined by an equation, you can supply your own arguments to create unique curves to achieve a particular type of velocity not 198 available by the predefined values. As shown in the charts below, you can recreate the standard set of values using a cubic-bezier function:

If you need slightly different curve for your UI elements, try to play around with the values until you achieve the effect you’re looking for


When an animation is not currently playing, it is set to fill mode state. The property animation-fill-mode fills a non-playing animation with a chosen set of properties, usually taken from first or last keyframes.

Possible values:

none / Do not apply any styles to the animated element before or after animation is executing.

forwards / Retain styles from the last keyframe (can be affected by animation-direction and animation-iteration-count.)

backwards / Get styles from the first keyframe (can be affected by animation-direction) also retain this style during animation-delay state.

both / Extend animation properties in both directions (forwards and backwards.)


Property animation-play-state specifies whether animation is running or paused.

Possible values:

paused / Animation is paused.

running / Animation is currently playing.

For example, you can pause animation on mouse hover:

Set animation state to paused.

Forward & Inverse Kinematics

There isn’t any out-of-the-box support for Inverse Kinematics in CSS. You have to write custom JavaScript to code the physics.

But, the effect can be simulated by using transform: rotate(degree) and transform-origin property to specify the pivot point between a parent and a child element.

Rotate around attachment point on root element.

The Root point is the place where the primary element is attached to either another parent element, or an imaginary static point in space. If Element A moves, it must affect Element B, in such way as if they were attached to each other at a Rotation Pivot Point.

This means, calculating all kinds of angles and lengths using trigonometric formulas. We can do this with JavaScript, or by using an existing vector / trigonometry library. But luckily, CSS already provides support for these types of element dynamics via the native transform-origin property

Forward Kinematics is when by moving Element A the movement of Element B is also affected (like a chain reaction) as though they are attached to each other at a shared pivot point.

Inverse Kinematics is the reverse of that: the physical movement of Element B affects Element A provided that it’s attached to some static point or another parent element. If not, the two elements can float in space :) This is a lot like bone joints in an animated character!

Night Stroll

Kyle Wetton is the creator of one of the greatest examples of inverse kinematics I have seen, used to make a walking cycle animation of a human figure entirely in pure CSS.

Issues. Every webdev has them. Published author of CSS Visual Dictionary https://amzn.to/2JMWQP3 few others…