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
.
transition-property
: The value of thetransition-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 settransition-property: font-size;
.transition-duration
: The value of thetransition-duration
property defines the length of time a transition animation should take to complete. By default, the value is0s
, meaning that no animation will occur.transition-delay
: The value of thetransition-delay
property specifies the duration to wait before the transition effect starts.transition-timing-function
: The value of thetransition-timing-function
property defines how intermediate values are calculated for CSS properties being affected by a transition effect. The most common values we see arelinear
(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) andease-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:
- Define a name for the set of keyframes.
- 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
.
animation-name
: The value of theanimation-name
property specifies the names of one or more@keyframes
at-rules that you want to apply to the element.animation-duration
: The value of theanimation-duration
property defines the length of time that an animation takes to complete one cycle.animation-iteration-count
: The value of theanimation-iteration-count
property could be any non-negative number orinfinite
. It defines the number of times an animation sequence should be played before stopping.animation-direction
: The value of theanimation-direction
defines whether an animation should play forward, backward, or alternate back and forth between playing the sequence forward and backward. It can benormal
(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), oralternate-reverse
(the animation reverses direction each cycle, with the first iteration being played backwards).animation-delay
: The value of theanimation-delay
defines the amount of time to wait from applying the animation to an element before beginning to perform the animation.animation-fill-mode
: The value of theanimation-fill-mode
defines how an animation applies styles to its target before and after its execution. It can benone
(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), orboth
(the animation will follow the rules for bothforwards
andbackwards
).animation-play-state
: The value of theanimation-play-state
defines whether an animation isrunning
orpaused
.animation-timing-function
: The value of theanimation-timing-function
defines how an animation progresses through the duration of each cycle. The most common values arelinear
,ease
,ease-in
,ease-out
, andease-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.
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
- Toptal CSS Sprites Generator
- CSS Sprite Generator from Dan’s Tool
- CodeShack Images to Sprite Sheet Generator
- 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
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
5. Animation Libraries
There are also many CSS animation libraries you could import into your project.