图片淡入需等load事件触发后设置opacity:1,避免闪现;必须预设宽高防布局抖动;iOS Safari需加transform: translateZ(0)硬件加速确保opacity过渡生效。

图片加载完成前就触发淡入,结果闪一下
浏览器默认会先显示空白区域,等图片加载完才渲染,这时用 opacity 动画就会看到“从无到有”的突兀闪现。真正要淡入的不是“图片本身”,而是“图片加载完成后的状态”。
必须等 img 元素的 load 事件触发后,再给它加过渡类——不能靠 CSS 的 transition 直接作用在初始 opacity: 0 上。
- 给
img设置初始样式:opacity: 0; transition: opacity 0.3s ease; - 用 JS 监听
img.onload,加载成功后立即添加一个类(如loaded),该类设opacity: 1 - 避免用
display: none或visibility: hidden初始隐藏,它们会破坏过渡触发条件
CSS transition 写在 img 还是父容器上?
写在 img 标签自身最直接可靠。如果写在父容器(比如 div),当图片尺寸变化或父容器重排时,可能意外触发过渡,造成非预期的淡入/淡出。
特别注意:不要对 width/height 做 transition 来模拟淡入——那是缩放或重绘,不是透明度变化,性能差且语义错误。
立即学习“前端免费学习笔记(深入)”;
- 只对
opacity和transform(如配合淡入做轻微位移)做 transition - 确保
img有明确的宽高(内联或 CSS 固定),否则加载中尺寸塌陷会导致布局抖动,干扰过渡观感 - 加
will-change: opacity可让浏览器提前优化,但仅在频繁切换的场景下考虑,普通图库不必加
替换图片时如何实现淡出+淡入连贯效果?
单纯改 img.src 会导致旧图立刻消失、新图加载完再淡入,中间有空白。要连贯,得保留旧图直到新图加载完成,并控制两者的 opacity 交叉过渡。
核心是“双图层”临时叠加:新图加载中时,旧图保持可见;新图一就绪,旧图 fade out,新图 fade in。
- 用 JS 创建一个新
img元素,设置src并监听其load事件 - 新图加载成功后,给旧图加
fade-out类(opacity: 0),同时给新图加fade-in类(opacity: 1) - 用
getComputedStyle检查旧图 transition 是否结束,再移除旧图 DOM 或回收引用 - 避免用
setTimeout硬等时间,因为不同设备/网络下动画时长可能不一致
移动端 Safari 图片淡入卡顿或失效
iOS Safari 对 opacity transition 在 img 上的支持曾长期有问题,尤其配合 will-change 或父容器有 transform 时容易掉帧甚至跳过动画。
最稳妥的兼容写法是:不用 opacity,改用 transform: translateZ(0) 强制 GPU 加速,并确保 img 是独立合成层。
- 给
img加transform: translateZ(0); backface-visibility: hidden; - 过渡仍用
opacity,但必须搭配上述硬件加速声明 - 避免在
img上同时设置filter(如blur)和opacity过渡,Safari 会拒绝渲染 - 测试时务必真机连接 Safari 开发者工具,模拟器行为不可靠



















