最轻量兼容的淡出动画需用 opacity + transition,初始状态必须设 opacity: 0 并在基础类中声明 transition,避免 display: none 中断动画,移动端需加 transform: translatez(0) 触发 gpu 加速。

直接用 opacity + transition 实现淡出动画
淡出动画最轻量、兼容性最好的方式就是改 opacity 配合 transition,不用 JS 也能触发,但必须写对初始状态和过渡声明。常见错误是只设 opacity: 0 却没配 transition,结果图片“啪”一下消失,没有过程。
-
transition必须写在基础类里,比如.img-fade { opacity: 0; transition: opacity 0.3s ease-out; },不能只写在.img-fade.show里 - 初始状态(非 hover / 非 active)必须有
opacity: 0,否则浏览器不知道“从哪开始变” - 想让淡出后彻底释放布局空间,不能同时设
visibility: hidden—— 它不支持过渡,一加就中断动画;得监听transitionend事件再设display: none - 移动端要注意:
opacity变化默认不触发 GPU 加速,卡顿明显;建议加transform: translateZ(0)或will-change: opacity
JS 控制淡出并移除图片的正确时序
很多代码写成 el.style.opacity = '0'; el.remove();,结果图片直接消失,毫无动画。这是因为浏览器把两步合并渲染了,根本没机会过渡。
- 正确做法是先设
opacity: 0,再强制重排:el.offsetHeight;,再设display: none或调用remove() - 更健壮的写法是操作 class:
el.classList.add('fading');→el.offsetHeight;→el.classList.add('hidden');,然后在 CSS 里用transitionend触发remove() - 如果用
setTimeout等待动画时间(如 300ms),要确保和 CSS 中transition时长一致,否则容易提前或滞后 - 多个图片批量淡出时,别用
for同步触发,会卡顿;可用setTimeout错开 20–50ms 起始时间
避免 display: none 导致动画失效
display: none 本身不可动画,任何对它的 transition 声明都无效。有人写 transition: all 0.3s,结果淡出一半就突然消失,就是因为 display 切换瞬间生效,打断了 opacity 过渡。
- 绝对不要给
display写transition,写了也白写 - 想“视觉消失+保留点击穿透”,用
opacity: 0+pointer-events: none,不是visibility: hidden - 想“视觉消失+释放空间”,必须等
transitionend回调里再设display: none或调用remove() - 用
visibility: hidden代替display: none?不行——它仍占位、可聚焦、可响应事件,只是看不见
Firefox 和 Safari 对 mask-image 淡出的支持陷阱
想用 mask-image 做渐变淡出(比如图片底部慢慢隐去),很容易在 Firefox 或 Safari 里全黑或全显,不是代码写错,是浏览器行为差异。
- Safari 不认
transparent,必须用灰度值:mask-image: linear-gradient(to bottom, #000, #fff),写black/white别名也不稳 - Firefox 目前完全忽略
mask-image: linear-gradient(),得换 SVG 方案:mask-image: url("data:image/svg+xml;utf8,<svg>...</svg>#m"),且必须带#m锚点 - Chrome/Edge 要加前缀才生效:
-webkit-mask-image和mask-image得同时写 -
mask-repeat: no-repeat和mask-size: 100% 100%必须显式声明,否则可能平铺或缩放错位
opacity: 0 就立刻 remove(),结果动画根本没跑完——过渡是否完成,得靠事件或精确计时,不能凭感觉。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











