transition 不自动管理 dom 结构切换,需 js 控制状态+css 显式声明可过渡属性;必须确保属性值真实变化、避免 display 切换、只过渡 transform/opacity、谨慎使用 all 和 transitionend,view transitions api 与之无关。

transition 本身不管理结构切换,只响应属性值变化;想让 DOM 替换(比如换页、切菜单)有动画,必须配合 JS 控制状态 + CSS 显式声明可过渡属性。
transition 不会自动响应 display 或 class 切换
加一个 fade-in 类,但元素原本 opacity: 1,而该类也设 opacity: 1,浏览器根本没检测到变化,动画就不会触发。同理,display: none → block 是不可过渡的,transition 完全无视它。
- 必须提前声明初始态:比如
.page { opacity: 0; transform: translateY(10px); } - 避免
display: none—— 改用visibility: hidden; opacity: 0;配合pointer-events: none - 加类前强制重排:
element.offsetHeight(或读任意布局属性),让浏览器“记住”旧值 - 过渡目标值必须真实变化,不能两端都是
opacity: 1或都未声明
transition-property 写 all 很危险
写 transition: all 0.3s ease 看似省事,但容易把本不该动的属性也卷进来,比如意外过渡了 height 引发重排,或过渡了 box-shadow 导致性能抖动。
- 只列真正要动的属性:
transition: opacity 0.3s ease, transform 0.3s ease - 优先选
transform和opacity—— 它们走 GPU 合成层,不触发重排重绘 - 避开
width、height、left、top、margin等会触发布局计算的属性 - 如果要用
will-change提前提示,只对正在过渡的元素设:will-change: transform, opacity
transitionend 事件监听总不准确
一个元素同时过渡 opacity 和 transform,transitionend 就会触发两次 —— 如果你只监听一次就移除类,可能 transform 还没结束,动画就被截断了。
- 监听时加属性过滤:
if (e.propertyName === 'transform') - 或者用
getComputedStyle(element).transitionProperty动态判断哪些属性在动 - 更稳妥的做法是统一用固定时长(比如都设
0.3s),然后用setTimeout延迟清理,避开事件竞态 - 注意事件冒泡:子元素过渡也会冒泡到父级,建议用
e.stopPropagation()或监听具体目标元素
View Transitions API 不是 transition 的升级版
很多人以为 document.startViewTransition() 是给页面切换加个“高级 transition”,其实它完全不依赖 CSS transition 属性,也不受其控制。它靠的是浏览器在 DOM 更新前后自动捕获快照,再合成过渡帧。
- 必须用
document.startViewTransition(() => { /* 同步改 DOM */ })包裹,里面不能有await或异步逻辑 -
view-transition-name必须成对、唯一、大小写敏感,且旧/新元素都得已挂载到 document 中 - 旧元素在快照前不能是
display: none、visibility: hidden或opacity: 0—— 至少得是opacity: 0.001或占位 - 自定义动画要通过
::view-transition-old和::view-transition-new伪元素,不是改原始元素样式
最常被忽略的一点:transition 生效的前提是“属性值真变了”,而不是“你希望它变”。DOM 结构替换、路由跳转、框架 re-render,这些本身都不触发 transition —— 你得亲手把变化落到可动画的 CSS 属性上,并确保浏览器能捕捉到那个“从 A 到 B”的过程。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











