CSS 动画(animation)允许你通过定义关键帧(@keyframes)来创建复杂的动画效果,这些动画效果可以应用于 HTML 元素上。下面是 CSS 动画的详细讲解,包括核心概念、使用方法以及相关属性。
核心概念
-
关键帧(
@keyframes)- 定义了动画的关键步骤。你可以指定在动画的不同阶段元素应该如何变化。
- 每个关键帧通过百分比(从
0%到100%)或关键字(如from和to)来定义。
-
动画属性(
animation)- 应用于元素上,用于控制动画的整体行为,包括动画名称、持续时间、时间函数等。
基本语法
定义关键帧
@keyframes animationName {
0% {
/* 初始状态 */
transform: translateX(0);
}
50% {
/* 动画的中间状态 */
transform: translateX(100px);
}
100% {
/* 结束状态 */
transform: translateX(0);
}
}
应用动画
.element {
animation-name: animationName; /* 动画名称 */
animation-duration: 2s; /* 动画持续时间 */
animation-timing-function: ease-in-out; /* 动画时间函数 */
animation-delay: 1s; /* 动画延迟时间 */
animation-iteration-count: infinite; /* 动画迭代次数(无限次) */
animation-direction: alternate; /* 动画方向(交替播放) */
}
常用动画属性
-
animation-name: 指定动画的名称,对应@keyframes中定义的动画。animation-name: exampleAnimation; -
animation-duration: 设置动画的持续时间,单位可以是秒(s)或毫秒(ms)。animation-duration: 2s; -
animation-timing-function: 定义动画的时间函数(加速度曲线),控制动画的速度变化。-
常用值:
linear(匀速)ease(默认,逐渐加速和减速)ease-in(逐渐加速)ease-out(逐渐减速)ease-in-out(加速后减速)
animation-timing-function: ease-in-out; -
-
animation-delay: 设置动画的延迟时间,单位可以是秒(s)或毫秒(ms)。animation-delay: 1s; -
animation-iteration-count: 设置动画的迭代次数,可以是具体次数或infinite(无限次)。animation-iteration-count: 3; /* 动画执行3次 */ animation-iteration-count: infinite; /* 无限次 */ -
animation-direction: 设置动画的播放方向。-
常用值:
normal(正常播放)reverse(反向播放)alternate(每次播放后反向播放)alternate-reverse(每次播放后反向播放,初始播放方向与reverse相反)
animation-direction: alternate; -
-
animation-fill-mode: 设置动画播放结束后的状态。-
常用值:
none(默认,不改变状态)forwards(保留动画结束时的样式)backwards(保留动画开始时的样式)both(同时保留开始和结束时的样式)
animation-fill-mode: forwards; -
-
animation-play-state: 控制动画的播放状态。-
常用值:
running(播放)paused(暂停)
animation-play-state: paused; -
示例:简单的动画效果
假设我们要创建一个简单的动画,使元素从左到右移动:
HTML:
<div class="box"></div>
CSS:
@keyframes moveRight {
from {
transform: translateX(0);
}
to {
transform: translateX(100px);
}
}
.box {
width: 50px;
height: 50px;
background-color: #4caf50;
animation-name: moveRight;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}
在这个示例中:
@keyframes moveRight定义了一个简单的动画,从translateX(0)移动到translateX(100px)。box类应用了这个动画,并设置了持续时间为 2 秒,时间函数为ease-in-out,以及无限次循环播放。
通过这些属性,你可以创建各种动画效果,包括平移、旋转、缩放等。 CSS 动画提供了丰富的功能来实现流畅和动态的用户界面。
性能较好的原因
使用 animation: move 2s forwards; 定义 CSS 动画被认为是性能较好的方法之一,主要有以下几个原因:
1. 硬件加速
- GPU 加速:大多数现代浏览器都会对 CSS 动画启用 GPU 加速,尤其是涉及到
transform和opacity属性的动画。当使用@keyframes进行动画定义时,浏览器通常会将动画操作交给 GPU 处理,而 GPU 擅长处理这些图形变化,从而减少了 CPU 的计算压力,使得动画更加流畅。
2. 非阻塞渲染
- 独立于主线程:CSS 动画通过
@keyframes定义,动画的执行不会阻塞浏览器的主线程。这意味着即使在动画执行时,JavaScript 的其他操作(如事件监听、DOM 操作)仍然可以正常进行,不会因为动画的存在而导致卡顿或延迟响应。 - css动画在渲染线程(合成线程) :专门处理渲染相关的任务,如绘制页面内容到屏幕上。它负责管理图层的合成,特别是当动画涉及到 GPU 加速时。
3. 动画逻辑简单明了
- 简化代码:通过 CSS 定义动画,可以将所有与动画相关的逻辑封装在样式表中,使得代码结构清晰,样式与行为分离。相较于 JavaScript 实现的动画,这种方式更简洁,而且容易维护。
4. 浏览器优化
- 浏览器优化:浏览器对 CSS 动画的优化非常完善。使用 CSS 动画,浏览器可以更好地进行帧优化和合成层的管理,减少了不必要的重排和重绘。这是因为浏览器能够预先计算动画的每一帧,并在渲染时直接使用,而不是像 JavaScript 动画那样需要逐帧计算和渲染。
5. 简化控制与回收
- 自动完成与回收:
forwards关键字会让动画在播放完后保持在最后一帧的状态,并且不需要额外的 JavaScript 代码来控制动画的回放状态。浏览器在动画完成后会自动回收资源,使得动画的生命周期管理更加简单和高效。
6. 避免布局抖动
- 减少布局计算:CSS 动画通常可以避免引起布局抖动(layout thrashing),因为它们使用的是
transform或opacity这种不会触发重排的属性,而 JavaScript 动画如果涉及到改变元素的top、left等位置属性,则可能会触发重新布局,影响性能。
在 CSS 动画(animation)中使用 transform 不会触发重排(reflow),主要是因为 transform 属性只涉及到元素的渲染层次的变化,而不涉及元素的实际布局结构。这些是主要原因:
Transform 属性的工作原理
transform属性用于对元素进行二维或三维转换,例如平移(translate)、旋转(rotate)、缩放(scale)等。这些转换是基于元素的渲染树进行的,不改变元素的实际位置和尺寸在文档流中的表现。- 这些转换是在 GPU 上进行的,这意味着它们不会影响页面的布局计算。
重排和重绘的区别
- 重排(Reflow) :当元素的尺寸、位置或文档结构发生变化时,会重新计算元素的位置和尺寸,这个过程称为重排。重排会影响到布局的计算,通常比较昂贵。
- 重绘(Repaint) :当元素的颜色、背景等视觉效果发生变化时,浏览器会重新绘制这些元素,但不涉及元素的布局计算。变换(
transform)会触发重绘,但不会触发重排。
Transform 不改变文档流
- 当你使用
transform对元素进行操作时,元素在视觉上的位置会变化,但它在文档流中的位置保持不变。浏览器只是在渲染层次中改变元素的视觉表现,而不需要重新计算整个布局。
什么时候 animation 是最佳选择?
- 当你需要实现复杂的、多步骤的动画时,CSS
animation是最佳选择。比如,从左上角移动到右下角,并且保持最终位置,这种动画通过@keyframes定义不仅简单,而且高效。
代码示例
.box {
width: 50px;
height: 50px;
background-color: red;
position: absolute;
top: 0;
left: 0;
animation: move 2s forwards;
}
@keyframes move {
100% {
top: 100vh; /* 页面底部 */
left: 100vw; /* 页面右侧 */
transform: translate(-100%, -100%); /* 确保元素完全位于右下角 */
}
}
适用场景
- 平滑移动:例如页面中的浮动按钮、加载动画等。
- 渐变效果:例如背景颜色渐变、透明度渐变等。
- 小型动画:例如按钮点击的视觉反馈、小图标的动效等。
总结来说,使用 animation 和 @keyframes 来定义动画的方式不仅简洁,而且性能出色,适合大多数需要实现平滑、复杂动画的场景。