opacity 配合 transition 实现淡入淡出需满足三前提:初始 opacity 显式声明、transition 写在默认状态、避免与 display: none 混用;否则动画不触发或跳过。

直接用 opacity 配合 transition 就能实现,但必须满足三个前提:初始值明确、过渡声明写在默认状态、避免和 display: none 混用——否则动画根本不会触发。
transition 必须写在默认状态里,不能只写在 :hover 或 .show 里
浏览器只对「有变化的属性」做过渡计算,如果 transition 声明只出现在伪类或动态类中,首次状态切换时没有“上一帧”可比,动画就跳过。比如下面这样是无效的:
.box:hover {
opacity: 0.3;
transition: opacity 0.3s ease; /* ❌ 错误:transition 写在 hover 里 */
}
正确写法是把 transition 放在基础选择器中,并确保默认有 opacity 值:
-
opacity初始值不能靠继承或浏览器默认(它默认是1,但显式写出更安全) -
transition必须在元素未激活时就存在,例如:.box { opacity: 1; transition: opacity 0.3s ease; } - 切换时只改
opacity值(如加.box.active { opacity: 0.2; }),不重复声明transition
别碰 display: none —— 它不支持过渡,且会中断 opacity 动画
很多人想“淡出后彻底隐藏”,于是同时设 opacity: 0 和 display: none。结果是:opacity 过渡还没走完,display: none 立刻生效,元素瞬间消失,动画戛然而止。
-
display是离散值,没有中间态,CSS 根本无法插值 - 若需淡出后释放布局空间,应在
transitionend事件里再设display: none,或改用visibility: hidden(它保持占位,但禁用交互) - 更稳妥的隐藏方案是结合
opacity+pointer-events: none,视觉与交互同步消失
JS 控制时容易跳帧:别连续赋值,要强制重排或分帧
用 JS 直接写 el.style.opacity = 0 后立刻写 el.style.opacity = 1,浏览器会合并渲染,看不到过渡过程。
- 最轻量的修复是触发一次重排:
el.style.opacity = 0; el.offsetHeight; el.style.opacity = 1; - 或者用
setTimeout把第二步推到下一帧:setTimeout(() => { el.style.opacity = 1; }, 0) - 推荐做法仍是操作 class:
el.classList.remove('visible'); setTimeout(() => el.classList.add('visible'), 0) - 注意:不要用
requestAnimationFrame手动控制 opacity,除非你做 Canvas 级精细动画——CSS transition 更省资源也更稳定
真正卡住人的往往不是语法,而是「过渡声明没提前写好」或「display 和 opacity 被同时修改」。这两个点漏掉一个,动画就静音了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











