CSS Animations — How to Make Elements Animate?

Sherry Li
8 min readDec 18, 2022

--

On most web pages, we are using static blocks to display dynamic content (e.g. text or images), but how to make elements animate on pages? There are many approaches such as CSS animations, SVG animations, Canvas animations, Lottie, etc. In this article, we will go through how to leverage the concepts of CSS animations to animate elements on web pages.

🇨🇳 To read this article in Chinese, please visit my Zhihu. 文章的中文版请戳我的知乎

1. Use the transition Property

If you only want some simple animation, it is good to use the transition property, which is a shorthand property for transition-property, transition-duration, transition-delay and transition-timing-function.

  1. transition-property: The value of the transition-property property is the CSS properties to which the transition effect should be applied. For example, if we want the transition effect to be set to an element’s font size change, then we should set transition-property: font-size;.
  2. transition-duration: The value of the transition-duration property defines the length of time a transition animation should take to complete. By default, the value is 0s, meaning that no animation will occur.
  3. transition-delay: The value of the transition-delay property specifies the duration to wait before the transition effect starts.
  4. transition-timing-function: The value of the transition-timing-function property defines how intermediate values are calculated for CSS properties being affected by a transition effect. The most common values we see are linear (the animation has the same speed from start to end), ease (default value, the animation has a slow start, then fast, before it ends slowly), ease-in (the animation has a slow start), ease-out(the animation has a slow end) and ease-in-out (the animation has a slow start and a slow end).
<div id="box">
Hover me
</div>
#box {
width: 100px;
height: 100px;
background: lightblue;
font-size: 15px;
transition: font-size 5s 2s ease-out;
/*
transition-property: font-size;
transition-duration: 5s;
transition-delay: 2s;
transition-timing-function: linear;
*/
}

#box:hover {
font-size: 50px;
}

💻 For more example code about the transition property, you could visit my CodePen.

You could visit MDN — transition to get a more complete understanding of the transition property.

2. Use @keyframes and the animation Property

To create more complex animations with CSS, another good approach is to use @keyframes and the animation property such that we can define a list of keyframes in the animation.

🔍 2.1 The @keyframes At-Rule

The CSS @keyframes at-rule controls the intermediate steps in a CSS animation sequence by defining styles for keyframes along the animation sequence.

To define a set of keyframes, we will:

  1. Define a name for the set of keyframes.
  2. One or more keyframes, each keyframe is composed of:

2a) from/to/a percentage value, which defines a percentage of the time through the animation sequence at which the specified keyframe should occur.

2b) The CSS styles for the specific keyframe.

You could visit MDN — @keyframes to get a more complete understanding of the @keyframes at-rule.

🔍 2.2 The animation Property

The animation property applies an animation between styles. It is a shorthand property for animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, and animation-play-state.

  1. animation-name: The value of the animation-name property specifies the names of one or more @keyframes at-rules that you want to apply to the element.
  2. animation-duration: The value of the animation-duration property defines the length of time that an animation takes to complete one cycle.
  3. animation-iteration-count: The value of the animation-iteration-count property could be any non-negative number or infinite. It defines the number of times an animation sequence should be played before stopping.
  4. animation-direction: The value of the animation-direction defines whether an animation should play forward, backward, or alternate back and forth between playing the sequence forward and backward. It can be normal (the animation plays forwards each cycle), reverse (the animation plays backwards each cycle), alternate (the animation reverses direction each cycle, with the first iteration being played forwards), or alternate-reverse (the animation reverses direction each cycle, with the first iteration being played backwards).
  5. animation-delay: The value of the animation-delay defines the amount of time to wait from applying the animation to an element before beginning to perform the animation.
  6. animation-fill-mode: The value of the animation-fill-mode defines how an animation applies styles to its target before and after its execution. It can be none (the animation will not apply any styles to the target when it is not executing), forwards (the target will retain the computed values set by the last keyframe), backwards (the animation will apply the values defined in the first relevant keyframe), or both (the animation will follow the rules for both forwards and backwards).
  7. animation-play-state: The value of the animation-play-state defines whether an animation is running or paused.
  8. animation-timing-function: The value of the animation-timing-function defines how an animation progresses through the duration of each cycle. The most common values are linear, ease, ease-in, ease-out, and ease-in-out.

You could visit MDN — animation to get a more complete understanding of the animation property.

2.3 Combine @keyframes and the animation Property to Create Animations

Now, let’s combine @keyframes and animation together!

<div id="ball-container">
<div id="ball" />
</div>
@keyframes move {
from {
top: 0;
left: 0;
}

25% {
top: 0;
left: calc(100% - 20px);
}

50% {
top: calc(100% - 20px);
left: calc(100% - 20px);
}

75% {
top: calc(100% - 20px);
left: 0;
}

100% {
top: 0;
left: 0;
}
}

#ball-container {
width: 100px;
height: 100px;
border: 2px black solid;
position: relative;
}

#ball {
width: 20px;
height: 20px;
border-radius: 50%;
background: red;
position: absolute;
top: 0;
left: 0;
animation: 8s linear 2s 2 move;
/*
animation-duration: 8s;
animation-timing-function: linear;
animation-delay: 2s;
animation-iteration-count: 2;
animation-name: move;
*/
}

💻 For more example code about the @keyframes at-rule and the animation property, you could visit my CodePen — @keyframes and CodePen — animation.

You could visit MDN — Using CSS animations to get a more complete understanding of how they are used to make animations together.

2.4 Pros ✅ vs. Cons ❌

Pros ✅:

  • High compatibility, you could check Can I use animation?.
  • Code is simple.
  • Web browsers can optimize the performance of CSS animations.
  • Takes less memory, and runs more smoothly.
  • For browsers with low FPS, CSS3 will downgrade automatically.

Cons ❌:

  • Can only achieve simple effects, but cannot combine different effects.
  • Cannot know the progress of animation.
  • Cannot play animations with motion curves.
  • If there are too many keyframes defined, the code will be tedious.

📃 References

📌 https://fe.ecool.fun/topic-answer/0139d2e8-67c1-40f9-868e-5f277e223629

3. Use Sprite Sheets to Create Frame-by-Frame Animations / Sprite Animations

🔍 3.1 Sprite Sheets

What is a sprite sheet?

A sprite sheet is a bitmap image file that contains several smaller graphics in a tiled grid arrangement. By compiling several graphics into a single file, you enable Animate and other applications to use the graphics while only needing to load a single file. This loading efficiency can be helpful in situations such as game development where performance is especially important.

An example of a sprite sheet

3.2 Use the background and background-position Properties to Create Sprite Animations

By using sprite sheets, we only need to load one image, then by moving the position of the image, we can achieve frame-by-frame animations. Therefore, we could load the sprite sheet in the background property, then the animation-timing-function’s steps() function will make the animation display the specific background-position of the sprite sheet in every keyframe accordingly.

<div id="sprite-animation" />
@keyframes sprite {
0% {
background-position: 0;
}

100% {
background-position: -1400px;
}
}

#sprite-animation {
width: 175px;
height: 309px;
background: url(https://miro.medium.com/max/1400/1*GJ6ZL0eX8tJE54ZYFSnI9Q.png)
no-repeat;
animation: 2s infinite steps(8) sprite;
}

💻 The above code example could also be found in my CodePen.

3.3 Pros ✅ vs. Cons ❌

Pros ✅:

  • Reduce the number of HTTP requests since only 1 image is required to be loaded. Therefore, faster page rendering speed.
  • The file size of the sprite sheet is smaller than the total of every single image’s file size.

Cons ❌:

  • Hard for maintenance if we need to add/delete any content on the sprite sheet.
  • Need to calculate the position of every frame accurately. How to make the image fit to different screens is a big challenge.
  • Need a box with a specific size to display the sprite animation.

3.4 Sprite Sheet Generators

  1. Toptal CSS Sprites Generator
  2. CSS Sprite Generator from Dan’s Tool
  3. CodeShack Images to Sprite Sheet Generator
  4. TexturePacker

📃 References

📌 https://helpx.adobe.com/ca/animate/using/create-sprite-sheet.html

📌 https://levelup.gitconnected.com/three-ways-to-animate-sprite-sheet-image-a5c000f0c579

📌 https://jelly.jd.com/article/6006b1035b6c6a01506c87a7

📌 https://juejin.cn/post/6844904152842108935

📌 https://www.cnblogs.com/hudingbiao/p/12078202.html

📌 https://stackoverflow.com/questions/3473151/what-are-the-pros-and-cons-of-a-sprite-sheet-compared-to-an-image-sequence

4. How to Optimize CSS Animations?

1. Use the transform property instead of width, height, margin, padding, etc. because transform is using the GPU to control, and it supports hardware acceleration.

2. Use 3D transformation to start the GPU acceleration. The performance of motions will be better by using transform property’s translate3d() function rather than using the left, right, top, and bottom properties.

<div id="ball-container">
<div id="ball1"></div>
<div id="ball2"></div>
</div>
#ball-container {
width: 200px;
height: 200px;
border: 2px solid;
position: relative;
}

/* Use 👇 */
#ball1 {
width: 50px;
height: 50px;
background: blue;
border-radius: 50%;
transform: translate3d(0, 0, 0);
transition: transform linear 3s;
}

#ball1.slide {
transform: translate3d(150px, 0, 0);
}

/* Replace 👇 */
#ball2 {
width: 50px;
height: 50px;
background: yellow;
border-radius: 50%;
position: absolute;
top: 100px;
left: 0;
transition: left linear 3s;
}

#ball2.slide {
left: 150px;
}

3. Reduce the use of the properties that harm your web performance (such as box-shadow, gradients, background-attachment: fixed;, etc.).

4. Try to make the animated elements out of the document flow using position: fixed; or position: absolute;.

5. If the animation has flicker (usually at the beginning of the animation), try to use:

-webkit-backface-visibility:hidden;
-moz-backface-visibility:hidden;
-ms-backface-visibility:hidden;
backface-visibility:hidden;

-webkit-perspective:1000;
-moz-perspective:1000;
-ms-perspective:1000;
perspective:1000;

📃 References

📌 https://www.programminghunter.com/article/48081087609/

📌 https://www.programminghunter.com/article/4975316848/

5. Animation Libraries

There are also many CSS animation libraries you could import into your project.

5.1 Element Animations

  1. anime.js
  2. Hover.css
  3. WickedCSS Animations
  4. Three Dots
  5. CSShake

5.2 Text Animation

  1. cssanimation.io

5.3 Transition Animations

  1. Animate.css
  2. Animista
  3. Magic Animations CSS
  4. Angry Tools CSS Animation Kit

--

--