页面首次加载transition静默失败的根本原因是浏览器首帧渲染时未获取到可插值的明确起始值,必须同时满足显式声明初始值(如opacity: 0)和在基础选择器中定义transition两个条件,且避免使用display: none。

transition为什么在页面首次加载时静默失败
根本原因不是代码写错了,而是浏览器首帧渲染时,没拿到可插值的明确起始值。比如只写了 .show { opacity: 1; transition: opacity 0.3s; },但没给元素默认状态声明 opacity: 0;,那浏览器计算出的初始 opacity 实际是 1(继承或默认值),变化量为 0,直接跳终态,过渡被跳过。
必须显式声明初始值和transition位置
两个条件缺一不可:初始值要写死,transition 要写在基础选择器里(即变化发生前就存在)。
-
opacity必须写opacity: 0;或opacity: 1;,不能靠未声明或继承 -
transform必须写transform: translateY(0);,不能只靠目标类里的translateY(100px) -
max-height初始值必须是具体数字,如max-height: 0;,终态写max-height: 500px;;height: auto不可过渡 -
transition必须写在默认样式中,例如#box { opacity: 0; transition: opacity 0.3s; },而不是只写在.show { opacity: 1; }里
用 display: none 的元素无法触发 transition
这是高频误踩点:display: none 会让元素完全脱离渲染树,所有 transition 彻底失效。
- 改用
visibility: hidden; opacity: 0;+transition: opacity 0.3s; - 如果需隐藏空间,再加
height: 0; overflow: hidden;,配合max-height过渡 - 避免混合使用
display和opacity控制显隐——display变化本身不可过渡,且会中断正在运行的 transition
requestAnimationFrame 不是万能解药
它只解决「时机」问题,不补「缺失的起点」。很多人加了 requestAnimationFrame 还是没动画,就是因为初始值根本没写。
- 正确用法:
el.classList.remove('hidden');(确保初始类含opacity: 0等)→requestAnimationFrame(() => el.classList.add('show')); - 错误写法:
requestAnimationFrame(() => el.classList.add('show'));,但.show是唯一类,且无默认opacity声明 - 注意:回调里别读取
offsetHeight或getComputedStyle,这会强制同步 layout,反而打断 transition 队列
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











