CSS动画仅两种底层实现:transition依赖属性值变化触发,非主动播放;@keyframes需正确命名、设duration和fill-mode等才生效;推荐用transform/opacity以触发GPU加速,避免reflow。

CSS 动画只有两种底层实现方式:用 transition 做状态过渡,或用 @keyframes + animation 做关键帧序列。其他所谓“动画效果”,都是这两者的组合、封装或变体。
为什么 transition 不能直接触发,必须靠状态变化?
transition 不是主动播放的动画,它只是对「属性值变化过程」的描述。浏览器只在检测到目标属性实际发生数值变更时(比如从 opacity: 1 → opacity: 0),才按你写的 transition 规则补中间帧。
- 常见错误:只写
.box { transition: opacity 0.3s; },但没定义 hover 或 class 切换后的opacity值 —— 动画根本不会动 - 伪类(
:hover、:focus)是最简单触发方式,但不适用于需要 JS 控制时机的场景 - JS 触发推荐用
element.classList.add("active"),而不是直接改style.opacity,否则可能绕过transition(因内联样式优先级高,初始态丢失) -
display、height(值为auto时)、font-size(单位混用如em和px)等属性无法过渡,会直接跳变
@keyframes 定义后,animation 不生效的典型原因
写了 @keyframes slideIn { from { transform: translateX(-100px); } to { transform: translateX(0); } },但元素没动?大概率卡在这几个点:
-
animation-name拼错,比如写成slidein(大小写敏感)或slide-In(中划线非法) -
animation-duration是0s或省略 —— 浏览器认为“无需动画”,直接跳到终态 - 动画绑定在
display: none元素上,或父容器有overflow: hidden且动画起始位置被裁剪,导致看不到位移 - 没设
animation-fill-mode: forwards,动画播完立刻回退到初始态,视觉上像“闪一下就没了” - 使用了不支持硬件加速的属性(如
top、left),在低端设备上卡顿甚至被降级为跳变
面试常问:transform 和 opacity 为什么更推荐用于动画?
因为它们能触发 GPU 合成层,避免重排(reflow)和重绘(repaint)主线程开销。浏览器只需更新图层位置/透明度,其余样式不变。
立即学习“前端免费学习笔记(深入)”;
- 用
transform: translateX(100px)替代left: 100px;用opacity: 0.5替代visibility: hidden或color: rgba(0,0,0,0.5) - 慎用
will-change: transform—— 它提前创建合成层,但滥用会导致内存占用飙升,仅在明确知道该元素即将动画且持续时间较长时加 -
max-height过渡看似能做展开收起,但因无法精确预估内容高度,常出现滚动条抖动或过渡不匀速;更稳方案是用transform: scaleY()+overflow: hidden
真正容易被忽略的是动画的“起点控制”:很多效果失败不是因为写错了 @keyframes,而是没意识到 animation-delay 是相对于元素插入 DOM 的时间,而非页面加载完成时间;如果元素是 JS 动态插入的,要确保 class 添加和动画触发之间没有竞态 —— 这才是线上 bug 最常藏身的地方。



















