animation是CSS3引入的动画属性,它允许开发者不借助JavaScript,仅用样式代码就让页面元素产生连续的动画效果。与transition只能做一次性的状态过渡不同,animation可以定义多个关键帧,控制动画播放次数、方向、延迟甚至暂停恢复,是前端动效开发中使用频率最高的能力之一。本文将从基本概念、子属性详解、实战示例和常见误区几个方面,系统讲清楚animation的用法。

animation的基本工作原理
要理解animation,首先要理解两个角色:一个是@keyframes关键帧规则,另一个是animation这一组属性。关键帧负责定义动画过程中各个时间点的样式状态,比如开始时元素是透明的,50%时变为不透明,结束时又回到透明;而animation属性则负责把这些关键帧“绑定”到具体元素上,并规定动画的时长、速度曲线、播放次数等执行细节。两者缺一不可,只写关键帧不写animation,动画不会生效;只写animation却没有对应名称的关键帧,元素也不会有任何反应。
下面是最简单的一个例子,让一个方块在两秒内从透明变为完全显示:
.box {
width: 100px;
height: 100px;
background: #4a90d9;
animation: fadeIn 2s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}这段代码中,from等价于0%,to等价于100%。中间还可以插入任意百分比的关键帧,例如25%、50%、75%等,浏览器会在相邻关键帧之间自动插值补间,形成平滑的动画。
animation的子属性详解
animation实际上是一个简写属性,它背后包含多个子属性,理解每一个子属性才能写出精准可控的动画。常用的子属性有以下八个。
animation-name:指定要使用的@keyframes名称,可以自定义命名,但不能是CSS保留字。
animation-duration:动画一次完整播放所需的时间,单位通常是秒(s)或毫秒(ms),例如2s或500ms。
animation-timing-function:速度曲线,决定动画在不同阶段的快慢节奏。常用值有ease(默认,先快后慢)、linear(匀速)、ease-in(先慢后快)、ease-out(先快后慢)、ease-in-out(两端慢中间快)。还可以用cubic-bezier自定义贝塞尔曲线,实现回弹等特殊效果。
animation-delay:动画开始前的延迟时间,支持负值。负延迟会让动画看起来从中间某一帧直接开始播放,常用于让多个元素错开却又不想等待太久的场景。
animation-iteration-count:播放次数,默认是1,可以写具体数字,也可以写infinite表示无限循环。
animation-direction:播放方向,可选值包括normal(正常)、reverse(反向)、alternate(正反交替)、alternate-reverse(反正交替)。其中alternate在做往返动画时特别实用,比如元素左右来回移动。
animation-fill-mode:控制动画开始前和结束后的样式状态。默认情况下动画结束后元素会回到原始样式,如果设置forwards,元素会保持在最后一帧的样子;设置backwards则在延迟期间就应用第一帧样式;both则两者兼顾。这是新手最容易忽略的一个属性,很多“动画结束后样式闪回”的问题都出在这里。
animation-play-state:控制播放或暂停,值为running或paused。可以通过JavaScript动态修改它,实现鼠标悬停时暂停动画之类的交互效果。
这些子属性可以用简写形式一次性声明,顺序上没有强制要求,但有两个时间值时,第一个会被解析为duration,第二个才是delay,这一点要特别注意:
.box {
/* 名称 时长 速度曲线 延迟 次数 方向 填充模式 */
animation: move 3s ease-in-out 1s infinite alternate forwards;
}
@keyframes move {
0% { transform: translateX(0); }
100% { transform: translateX(300px); }
}常见实战场景与代码示例
掌握了子属性之后,看几个实际开发中高频出现的场景。第一个是loading加载动画,用无限循环加alternate方向做一个呼吸感的转圈效果:
.loader {
width: 40px;
height: 40px;
border: 4px solid #e0e0e0;
border-top-color: #4a90d9;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}第二个场景是列表项依次入场。做法是给每个元素设置相同的动画,但用不同的animation-delay制造错落感。配合负延迟技巧,可以避免页面加载时先空白等待:
.item {
opacity: 0;
animation: slideUp 0.6s ease forwards;
}
.item:nth-child(1) { animation-delay: 0.1s; }
.item:nth-child(2) { animation-delay: 0.2s; }
.item:nth-child(3) { animation-delay: 0.3s; }
@keyframes slideUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}注意这里opacity: 0写在元素本身,加上forwards填充模式,保证动画结束后元素停留在可见状态。第三个场景是鼠标悬停时暂停动画,通过animation-play-state实现:
.banner:hover .banner-text {
animation-play-state: paused;
}animation与transition的区别及常见误区
很多人会把animation和transition混为一谈。两者的核心区别在于:transition需要触发条件(比如hover、class切换),并且只能在两个状态之间过渡一次;而animation只要绑定就会自动执行,可以定义多个关键帧、循环播放、控制方向。简单说,做简单的悬停变色、按钮反馈用transition就够了,做入场动画、循环动效、多阶段动画则应该用animation。
使用中有几个常见坑值得提醒。一是动画属性的选择:应该优先使用transform和opacity做动画,因为它们由GPU合成器处理,不会触发重排和重绘,性能远好于直接动画width、height、top、left这类会引发布局计算的属性。二是同名关键帧冲突问题,@keyframes是全局生效的,如果两个样式表中定义了同名关键帧,后加载的会覆盖先加载的,命名时建议加上业务前缀。三是简写中duration和delay的顺序问题,两个时间值的先后位置决定含义,写反了动画节奏会完全不对。四是想让动画结束后保持最终状态却忘了加forwards,导致样式回跳。
总结一下,animation由关键帧定义动画内容,由一组子属性控制执行方式,子属性中fill-mode和direction最容易被忽视却最影响效果。日常开发中优先动画transform和opacity,掌握这些要点后,绝大多数页面动效都可以用纯CSS优雅地实现。
css animation动画属性前端动画修改时间:2026-09-13 22:14:52