大部分页面都使用静态元素来显示动态内容(例如文字、图片),但如何让页面上的元素动起来?可以使用CSS 动画来让页面元素动起来。

1. 使用 transition 属性

如果你只是想要一些简单的动画或过渡效果,使用 transition 属性会是一个很好的办法。 transition 属性是 transition-propertytransition-durationtransition-delaytransition-timing-function 属性的简写属性。

  1. transition-propertytransition-property 属性的值设定了应用过渡在哪个 CSS 属性上。举个例子 ,如果我们想把过渡效果应用在字体大小改变时,那就应该设置 transition-property: font-size;
  2. transition-durationtransition-duration 属性的值以秒或毫秒为单位设定了过渡动画所需的时间。默认值为 0s,表示不出现过渡动画。
  3. transition-delaytransition-delay 属性的值设定了在过渡效果开始之前所需要等待的时间。
  4. transition-timing-functiontransition-timing-function 属性的值设定了如何计算因受到过渡效果影响的 CSS 属性产生的中间值是如何计算。最常见的值有 linear (动画从开始到结束是匀速的)、 ease (默认值,动画有一个缓慢的开始,然后变快,最后缓慢结束)、 ease-in (动画有一个缓慢的开始)、 ease-out (动画有一个缓慢的结束)和 ease-in-out (动画有一个缓慢的开始和结束)。
1
2
3
<div id="box">
Hover me
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
解释#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;
}

动图封面


2. 使用 @keyframesanimation 属性

如果想要实现一些更复杂的动画效果,可以尝试定义动画中的一些关键帧,使用 @keyframesanimation 属性来实现。

2.1 The @keyframes @规则

CSS 的 @keyframes @规则通过在动画序列中定义关键帧的样式来控制 CSS 动画序列中的中间步骤。

定义一系列的关键帧需要:

  1. 动画名称。

  2. 一个或多个关键帧,每个关键帧包含:

    1. fromto或一个百分值,定义了动画序列中出发关键帧的时间点。
    2. 关键帧的 CSS 样式。

2.2 animation 属性

animation 属性指定了一组或多组动画,每组之间用逗号相隔。它是 animation-nameanimation-durationanimation-timing-functionaniamtion-delayanimation-iteration-countanimation-directionanimation-fill-modeanimation-play-state 属性的简写属性。

  1. animation-nameanimation-name 属性的值指定应用的一系列动画,每个名称代表一个由 @keyframes 定义的动画序列。
  2. animation-durationanimation-duration 属性的值指定了一个动画周期的时长。
  3. animation-iteration-countanimation-iteration-count 属性的值定义了动画在结束前运行的次数,可以使任何非负数或是 infinite(无限循环)。
  4. animation-directionanimation-direction 属性的值规定了动画是否反向播放。它的值可以是 normal (每个循环内动画向前循环) 、 alternate (动画交替反向运行)、 reverse (反向运行动画)或 alternate-reverse (动画第一次开始时是返乡的,然后反相交替进行)。
  5. animatino-delayanimation-delay 属性的值定义了动画效果开始前需要的等待时间。
  6. animation-fill-modeanimation-fill-mode 属性定义了动画在执行之前和之后如何将样式应用于其目标。它的值可以是 none (当动画为执行前,动画将不会将任何掩饰应用于目标)、 forwards (目标将保留由执行期间遇到的最后一个关键帧计算值)、 backwards (动画将在与用语目标是立即应用第一个关键帧的计算值)或是 both ( 动画将遵循 forwardsbackwards 的规则)。
  7. animation-play-stateanimation-play-state 属性的值将定义一个动画是否运行(running)或者暂停(paused)。
  8. animation-timing-functionanimation-timing-function 属性的值定义了每一个动画周期中执行的节奏。最常见的值有 lineareaseease-inease-outease-in-out

2.3 把 @keyframesanimation 属性组合起来制作动画

现在,让我们把 @keyframesanimation 结合起来吧!

1
2
3
<div id="ball-container">
<div id="ball" />
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
解释@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;
*/
}

动图封面

3. 如何优化 CSS 动画?

  1. 因为 transform 支持硬件加速,所以使用 transform 属性来替代 widthheightmarginpadding 等属性。

  2. 使用 3D 变形来开启 GPU 加速。使用 transform 属性的 translate3d() 函数会让动画流畅度优于使用 leftrighttopbottom 属性。

1
2
3
4
解释<div id="ball-container">
<div id="ball1"></div>
<div id="ball2"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
解释#ball-container {
width: 200px;
height: 200px;
border: 2px solid;
position: relative;
}

/* 用 ↓ */
#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);
}

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

#ball2.slide {
left: 150px;
}
  1. 减少使用高消耗的属性(例如 box-shadowgradientsbackground-attachment: fixed;等)。

  2. 尽可能使用 position:fixed;position:absolute; 来让动画元素脱离文档流。

  3. 如果动画过程中出现闪烁(一般出现在动画开始时),尝试使用:

1
2
3
4
5
6
7
8
9
解释-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;