css动态效果无需javascript,核心是transition(用于状态切换)和@keyframes+animation(用于完整动作序列);选错会导致卡顿或失效。

直接说结论:CSS 动态效果不靠 JavaScript 就能实现,核心就两条路——transition 适合状态切换(比如 hover、focus),@keyframes + animation 适合定义完整动作序列(比如弹跳、路径移动)。选错会导致动画卡顿、无法触发,或根本不动。
什么时候该用 transition 而不是 animation
transition 只响应 CSS 属性的“变化”,比如从 opacity: 0 到 opacity: 1,或者从 transform: scale(1) 到 transform: scale(1.2)。它不是独立运行的动画,而是对“状态差”的平滑补间。
- 必须有明确的触发源:常见的是
:hover、:focus、:checked,或 JS 改 class 后的属性变更 - 只支持两个状态(起始 & 结束),不能定义中间帧
- 性能好:只要只动
transform和opacity,浏览器会走合成层,不触发重排 - 容易踩坑:写
transition: all 0.3s很危险——万一某次 JS 改了height或margin,就会强制重排,卡顿明显
推荐写法:transition: opacity 0.2s ease, transform 0.2s ease;
@keyframes 动画必须配 animation-name 才生效
@keyframes 只是“剧本”,不执行;真正播放靠元素上的 animation-name 属性绑定。漏写或名字拼错(比如大小写、空格、中文标点),动画就完全静止。
- 名字必须完全一致:
@keyframes slideIn { ... }→ 元素上必须写animation-name: slideIn;(不能是slidein或"slideIn") -
animation-duration为 0 或负值时,动画不播放(不是“瞬间完成”,是彻底禁用) - 如果元素初始状态和
0%关键帧不一致,动画开始会有“跳变”——建议显式设初值,或用animation-fill-mode: forwards;锁定终态 - 在移动端 Safari 上,
animation-timing-function: steps()有时不生效,可降级用cubic-bezier(0.1, 0.7, 1.0, 0.1)模拟
scroll-driven animations 不是所有浏览器都支持
animation-timeline: view(); 这类滚动驱动动画目前仅 Chromium 115+(Chrome / Edge)和 Safari 17.4+ 原生支持,Firefox 完全不支持。线上项目若要用,必须加降级逻辑。
- 检查支持性:
if ('animationTimeline' in CSS) { /* 启用 scroll-driven */ } - 降级方案:用
IntersectionObserver监听元素进入视口,然后手动加 class 触发transition或animation -
animation-range的单位是视口百分比(如entry 0%),但实际触发位置受父容器overflow和contain影响,调试时建议先关掉contain: layout paint;
transform 和 opacity 是唯二推荐无条件硬件加速的属性
其他属性(width、height、left、top、background-color)触发动画时,99% 情况下会触发 Layout → Paint → Composite 流程,尤其是列表滚动中做这些动画,必然掉帧。
- 想位移?用
transform: translateX(100px),别用left: 100px - 想缩放?用
transform: scale(1.5),别改width/height - 想渐隐?用
opacity: 0,别用visibility: hidden(后者不支持过渡) - 如果必须动颜色,优先选
color或border-color(Paint 阶段开销小),避开background-image或渐变色动画
最常被忽略的一点:动画元素如果父容器用了 will-change: transform,但子元素又频繁改 opacity,反而可能因图层分裂导致内存暴涨——只在真正需要时加 will-change,且用完即删。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











