前端一面:CSS 动效——transition 与 animation 常见考点
CSS 动效相关的问题,经常以「transition 和 animation 有什么区别」「为什么动画不生效」「性能有没有问题」这些形式出现在一面里。
这一篇不打算把所有属性逐条背一遍,而是先搞清楚几件事:transition 和 animation 的本质差异、各自适合解决什么问题,以及在项目和面试里常见的坑有哪些。
transition 和 animation 本质上有什么区别?
可以先把这两个东西抽象成两种不同的「时间线」:
transition:从一个状态「平滑过渡」到另一个状态- 需要某种「状态变化」触发:比如
:hover、class 切换、JS 修改样式。 - 更适合「单段」过渡:从 A → B。
- 需要某种「状态变化」触发:比如
animation:按照关键帧脚本驱动的一整段动画- 不一定需要外部状态变化,写上就能自动播放,也可以设为循环。
- 更适合多阶段、循环、复杂时间线的动效。
简单总结可以记成一句话:
- transition 像是「两个状态之间的过渡效果」,animation 更像是「带剧本的时间轴」。
transition:核心属性与常见踩坑
1. transition 的关键属性
在绝大多数场景里,真正常用的是这几个:
transition-property:需要过渡的属性,比如:opacity、transform、background-color、height等。
transition-duration:过渡的总时间,如0.3s、200ms。transition-timing-function:时间函数,控制「快慢曲线」:- 常见值:
ease、linear、ease-in、ease-out、ease-in-out、自定义cubic-bezier(...)。
- 常见值:
transition-delay:延迟多久再开始过渡,如0.2s。
通常会用简写来写多条属性的过渡:
1.btn {
2 transition: opacity 0.2s ease, transform 0.2s ease;
3}
2. 为什么 transition 有时候「不生效」?
常见原因可以归类成几种:
- 只在目标状态写了 transition
- 例如只在
:hover里写transition,默认状态没写。 - 结果是:移上去瞬间跳,移开时才有平滑效果。
- 更好的写法:把
transition写在默认状态,目标状态只改属性值。
- 例如只在
- 对不能动画的属性使用 transition
- 比如
display、visibility这种是直接切换,没有中间态。 - 一般会配合
opacity、transform、max-height等「可动画」属性来实现显示/隐藏。
- 比如
- 起点和终点一样
- 某些情况下,JS 多次设置了相同的值,或者计算出的结果一样,看起来就像没动。
3. 性能相关的注意点
在一面里,如果想把答题拉到更专业一点,可以提到:
- 优先对
transform、opacity做过渡- 这类属性通常只会引起合成层变化,可以更好地利用 GPU 加速。
- 慎重对
width、height、top、left做长期动画- 这些属性变化往往会触发布局和重排,频繁执行会带来性能问题。
用一句话概括就是:
- 能用 transform/opacity 解决的,就尽量不要用布局相关属性做动效。
animation:关键帧 + 控制参数
1. @keyframes:定义「剧本」
animation 的核心是关键帧,可以用百分比或 from/to 来写:
1@keyframes fade-in-up {
2 from {
3 opacity: 0;
4 transform: translateY(10px);
5 }
6 to {
7 opacity: 1;
8 transform: translateY(0);
9 }
10}
更复杂的动效可以有多段关键帧:
1@keyframes pulse {
2 0% { transform: scale(1); }
3 50% { transform: scale(1.05); }
4 100% { transform: scale(1); }
5}
2. animation 的常用属性
动画名和时长是最基本的两个:
animation-name:要使用的关键帧名称,如fade-in-up。animation-duration:持续时间,如0.4s。
其他常见控制项:
animation-timing-function:时间函数。animation-delay:延迟。animation-iteration-count:执行次数,如1、2、infinite。animation-direction:播放方向:normal、reverse、alternate(往返)等。
animation-fill-mode:- 控制动画前后元素的样式生效情况:
none、forwards、backwards、both。 - 入场动画常用
forwards,让元素停在最后一帧。
- 控制动画前后元素的样式生效情况:
animation-play-state:running/paused,可以用 JS 控制暂停和继续。
一般写法会用简写:
1.card-enter {
2 animation: fade-in-up 0.4s ease-out 0s 1 forwards;
3}
3. animation 常见坑
- 动画结束后「回弹」到初始状态
- 原因:没设置
animation-fill-mode: forwards;。
- 原因:没设置
- 想多次触发动画却只播放第一次
- class 一直挂在元素上,浏览器认为已经播放完成,不会重新播放。
- 常见解决思路:移除 class 强制重绘,再加回;或者通过改变
animation-name强制重跑。
- 无限循环动画性能问题
- 大面积元素或多个复杂动画同时
animation-iteration-count: infinite,在低端设备上很吃性能。 - 实战里通常只让小范围元素做简单循环,并控制关键帧逻辑尽量轻量。
- 大面积元素或多个复杂动画同时
什么时候用 transition,什么时候用 animation?
在日常写页面和面试答题时,可以按照场景来区分:
- 优先考虑用 transition 的场景
- 元素有明确的「前后两种状态」:
- 按钮 hover、active。
- 折叠面板展开/收起。
- 弹窗从隐藏到显示的简单淡入。
- 只需要在状态切换时平滑过渡,不需要自动循环。
- 元素有明确的「前后两种状态」:
- 适合用 animation 的场景
- 需要「自动运行」或「循环」的效果:
- loading spinner、骨架屏、心跳/呼吸效果。
- 需要多阶段的复杂时间线:
- 入场动画:先从下方滑入,再略微弹一下。
- 轮播图的复杂切换节奏。
- 需要「自动运行」或「循环」的效果:
可以记一个简单判断:
- 如果只是状态 A ↔ B 之间的切换,先考虑 transition;如果需要一段编排好的时间轴或循环动效,再考虑 animation。
面试里常见的延伸问题
1. 「transition 和 animation 的本质区别是什么?」
可以从三个角度回答:
- 触发方式不同:
- transition 需要状态变化触发。
- animation 可以自动或循环播放。
- 描述方式不同:
- transition 只描述「怎么从当前值过渡到目标值」。
- animation 通过 keyframes 描述一整段时间轴。
- 使用场景不同:
- transition 更适合交互态的细节过渡。
- animation 更适合复杂、独立于交互的动效。
2. 「为什么我的动画看起来很卡?有哪些优化手段?」
可从这几方面展开:
- 检查动画的是哪些属性:
- 优先使用
transform/opacity。 - 避免持续动画
width/height/top/left。
- 优先使用
- 控制参与动画的元素数量和层级:
- 大面积背景、复杂阴影、模糊等效果在低端设备上非常吃性能。
- 在必要时使用
will-change提示:- 如
will-change: transform;,但不要滥用,以免占用过多内存。
- 如
3. 「如何兼顾动效和可访问性?(prefers-reduced-motion)」
如果面试官比较关注用户体验,可以顺带提到:
- 可以使用媒体查询
@media (prefers-reduced-motion: reduce):- 当用户系统偏好「减少动态效果」时,降低动画强度或者直接关掉非必要动画。
示例:
1@media (prefers-reduced-motion: reduce) {
2 * {
3 animation-duration: 0.01ms !important;
4 animation-iteration-count: 1 !important;
5 scroll-behavior: auto !important;
6 transition: none !important;
7 }
8}
这种细节在一面里提到,会明显加分。
小结:如何在一面里讲清楚 CSS 动效?
围绕 transition 和 animation,答题时可以沿着这样的思路:
- 先用一两句话说明它们在触发方式和使用场景上的区别。
- 再分别举 1–2 个典型应用场景和常见坑(比如属性选择、fill-mode、性能问题)。
- 如果时间允许,可以补充一点关于「性能优化」和「可访问性」的思考。
只要沿着「解决什么问题 → 适合哪些场景 → 有哪些容易踩的坑」这个框架来讲,CSS 动效相关的问题通常都能比较系统地答清楚。