How to make CSS Animations | Imaginary Cloud

Animations on the internet are not new. They have been used to achieve many goals, including making something more interesting to watch or even more appealing. Sometimes that is what makes a website stand out among the competition! Animations can make UI elements resemble the real world, making them smoothly change while giving the feeling of continuity, action and progress, instead of changing in a blink of an eye.

Even when applied to small elements, animations can help the user remember whether an action was executed or not. In fact, the user is more likely to remember what he/she just did after perceiving something changing little by little, instead of all at once. A simple animation for a loading screen tells more than just waiting with a white page. It’s the difference between knowing something is still happening and wondering if the page is broken.

What are CSS animations?

CSS offers two different types of animations. The first one is the transition property, which is frequently used for hover effects and other user interactions. The second one is the animation property, which allows creating more continuous animations or, as we will see later, animations with more stages. Check the example of these two properties’ effects on the codepen below (if you don’t know what codepen is, check our article about this great tool for sharing code snippets):

  • at the left an hover effect using the transition property;
  • at the right a loading effect using the animation property.

Key elements of animations

Animation Timing

transition: all 0.5s linear 0s; animation: rotate 1s linear infinite 0.1s;

Below, there are four examples that show the multiple effects that different values can create: two hover effects (one with a duration of 0sec and another 0.5sec), together with two loading effects (one with a delay of 0sec and another with 0.1sec, 0.2sec, and 0.3sec for each of the squares).

Inner Components

//HTML structure <div class="my_text"></div> /* CSS styling */ my_text { ... } my_text:before { content : " " ; ... } my_text:after { content : " " ; ... }

They can be styled as usual on your CSS file, but it won’t be necessary to define them on the HTML. It will automatically associate the extra elements with the main component, leaving the HTML intact. The only difference in the CSS is that you need to define the property content represented by a string. As an example, it’s like describing the text inside a div on the HTML. From the hover effect example, check below how the a:before component was styled and an empty string was used on the content property to only create that little corner.

a { color: #FCD63F; font-size: 35px; text-decoration: none; text-transform: uppercase; padding: 5px 10px; margin: 0px 10px; position: relative; transition: all .5s } a:before { content: ""; position: absolute; bottom: -8px; left: -8px; width: 12px; height: 12px; border: 3px solid #FCD63F; border-width: 0 0 3px 3px; opacity: 1; transition: all 0.3s }

In case the animation needs more than two extra elements, standard HTML components can be used. Change the HTML structure and incorporate unstyled components like spans, apply styling, and then apply the transition or animation. The use of multiple components is also useful if you have different types of movements once each component can only take one animation or transition at a time. The example below shows the loading effect: there is a div named container with four spans inside, and the container has one animation which makes it get bigger. Finally, each span has an animation that makes them rotate.

//HTML structure <div class="container"> <span></span> <span></span> <span></span> <span></span> </div> /* CSS styling */ .container { width: 90px; height: 90px; position: relative; animation: animate 1s linear infinite; transform: rotate(45deg); } .container span { position: absolute; width: 45px; height: 45px; animation: rotate 1s linear infinite; }

CSS transitions

Let’s check what these last two properties are and how do they work:


transition: color 0.5s linear 0.5s, background-color 0.1s linear 0.5s; // instead of transition: all 0.5s linear 0.5s;


  • linear, the velocity will be constant;
  • ease-in, it will start slow and then get faster;
  • ease-out, it will start fast and then get slower;
  • ease-in-out, a mix of the last two: it will start slow, then get faster and slower again;
  • ease, is a variation of the previous one and the default value of this property.

Explore how these different values can affect an animation in the example below. Notice that the transition can keep track of itself. Moving the mouse quickly in and out of the animated component, the animation will not go all the way till the end: it will rollback.

CSS animations and keyframes

@keyframes rotate { 0% {transform: rotate(0deg);} 10% {transform: rotate(0deg);} 50% {transform: rotate(90deg);} 90% {transform: rotate(90deg);} 100% {transform: rotate(90deg);} } span { position: absolute; width: 45px; height: 45px; animation: rotate 1s linear infinite; }

Just like the transition property, the animation one is also the composition of other properties. They are: animation-duration, animation-delay and animation-timing-function, that work in the same way as the transition ones; animation-name, where the name of the keyframe appears; animation-iteration-count, to determine how many times the animation will run, which can be a specific number of “infinite”; animation-direction and animation-fill-mode.


  • normal, the animation goes from 0% to 100% (default value);
  • reverse, the animation goes from 100% to 0%;
  • alternate, the animation goes from 0% to 100% and 0% again;
  • alternate-reverse, the animation goes from 100% to 0% and 100% again.


  • none, the component is set to its default style;
  • forwards, after the animation is complete, the component will remain as the animation left it;
  • backwards, before the animation starts, on delay time, the component will immediately take the style defined at the start of the animation.
  • both, before and after the animation, the component takes the style the animation defines.

Check the result of each value below. Just click on any of the boxes where the animation has one second of delay and the differences will be clear.

What CSS properties can be animated?

Even though unit/numeric properties can be changed smoothly, not all of them impact the rendering process the same way; some can be slightly heavier than others. When a browser initiates a web page, it will go through some steps: the first is Layout, the second is Paint, and finally, the Composite. If we choose to animate a property that triggers Layout, like width, the browser will repeat the paint and composite. For that reason, the use of properties that only activate the composite step, like transform and opacity should be prioritized. You can check the full list of CSS properties and their triggers.

Transform property

  • translate ( x , y ) — Move an element x pixels horizontally and y pixels vertically. Negative values will move left or up and positive ones will move right or down.
  • rotate( y ) — Rotate an element y degrees. Positive values for clockwise and negative for counter-clockwise movement. The effect will happen over the center of the element by default, change it with the transform-origin property.
  • scale( x , y ) — Alter the size of the element. Given two values, x and y, it will change the width of the element x times and the height y times. Given only one value, like w, it will change both width and height w times, keeping the initial proportion of the element. It can be used scaleX( x ) and scaleY( y ) to only target width or height correspondingly. Values above 1 make the element bigger and between 0 and 1 smaller.
  • skew( x , y ) — skews the element x deg horizontally and y deg vertically. You can specify only one value, but the effect will only affect the X-axis, the y will be set to 0. Just like scale, you can specify this action for the X and Y-axis individually with skewX() and skewY().
  • matrix( scaleX() , skewY() , skewX() , scaleY() , translateX() , translateY() ) — the matrix allows to easily combine all the methods above.

All the previous effects will be applied to the centre of the element unless the property transform-origin value is changed. That value can be 1 or 2 percentages or even the following values: top, bottom, right, left and centre.

If you tried to explore the code of some of the previous animations shown here, you may notice that we are not using the transform property all the time. However, that does not imply that you can not do the same animations using only transformations. To show that, we created both effects using the transform property. Check below all the alterations needed; you’ll be surprised by how easy it is to do the same effect without changing the HTML structure.

Performance of CSS Animations vs Javascript


Found this article useful? You might like these ones too!

Originally published at on October 29, 2020.

Applying our own Product Design Process to bring great digital products to life |

Applying our own Product Design Process to bring great digital products to life |