直接改img的src会导致空白闪动,因浏览器先清空再加载,必须用叠层opacity控制显隐或transform移动容器实现平滑过渡。

图片切换时直接改 src 会导致空白闪动,单纯加 transition: opacity 0.5s 也压不住——因为浏览器在加载新图前会清空旧图,过渡断在中间。真正能用的方案只有两种:叠层控制显隐,或用 transform 移动容器。选错方式,动画就卡、闪、掉帧。
为什么不能直接对 img 元素用 opacity 过渡?
常见错误是只写一条 CSS:
.slider-img { opacity: 1; transition: opacity 0.4s; }
然后 JS 里直接 el.src = nextSrc。问题在于:src 切换瞬间,浏览器会先清空图像内容(变成透明/空白),再触发加载,此时 opacity 已经从 1 变成 0,但新图还没载入完成,用户看到的就是“黑屏”或“白块”。
- 必须把淡出、换图、淡入拆成三步,用 JS 控制时机
-
transition必须限定为opacity,不能写all,否则可能意外触发布局重算 - 新图
src设置后,要等load事件或固定延迟(与 CSS 时长一致)再开淡入,否则可能淡入时图还是空的
用绝对定位叠层 + class 切换实现淡入淡出
这是最轻量、兼容性最好、也最容易调试的方式。所有图片放在同一位置,靠 opacity 和 z-index 控制显示顺序。
立即学习“前端免费学习笔记(深入)”;
- HTML 结构:多个
<img>并列,父容器设position: relative - CSS 中每张图设
position: absolute; top: 0; left: 0; opacity: 0; transition: opacity 0.5s ease-in-out - 当前显示图加
.active类,对应opacity: 1;其他图保持opacity: 0 - JS 切换逻辑:先移除所有
.active,给下一张加.active—— 浏览器自动触发 opacity 过渡
注意:不要用 display: none 替代 opacity: 0,它会中断过渡、且无法触发 transition。
用 transform: translateX() 实现滑动轮播
如果要做左右滑动效果(比如手机端轮播),千万别用 left 或 margin-left 动画——它们强制浏览器每帧重排布局,低端机上明显卡顿。
- 正确做法:把所有图片包进一个
<div class="slides">,设display: flex或white-space: nowrap -
.slides自身设transform: translateX(-300px)(假设每张宽 300px),过渡只加在该容器上:transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) - 每次切换只更新
.slides的transform值,不操作单个img元素 - 务必确保父容器有固定宽高和
overflow: hidden,否则滑动会溢出
这个方案 GPU 加速,60fps 稳定,但 DOM 结构稍重,适合 3–10 张图的场景。
哪些情况必须放弃 CSS 过渡,改用 <canvas>?
当你要做遮罩擦除、像素溶解、径向渐变过渡这类非标准效果时,CSS 的 opacity 和 transform 就不够用了。
-
<canvas>能逐帧控制两张图的混合比例(用globalAlpha)、叠加模式(globalCompositeOperation)甚至像素级运算 - 代价是 JS 逻辑变复杂,需监听
image.onload、手动调用requestAnimationFrame,且无法被 CSS 动画工具链优化 - 移动端要注意 canvas 渲染性能,建议限制尺寸(如不超过视口宽高的 1.5 倍),并避免每帧都
clearRect+ 重绘整图
普通网站轮播,80% 场景用叠层 + opacity 就够了;滑动需求明确、性能敏感的,优先选 transform 方案;只有设计师提了“水波纹入场”这种需求,才值得碰 canvas。



















