应使用 opacity 过渡替代 background-image 过渡,因后者多数浏览器不支持;典型做法是两张图叠放,通过 opacity 控制显隐,并预加载图片、设固定宽高、明确 background-size 和 background-position 避免闪屏与重排。

用 transition 配合 background-image 实现平滑切换
直接改 src 不会触发动画,浏览器把图片替换当成“重绘”,不是“属性变化”。真正能过渡的只有 CSS 属性,所以得绕道用 background-image + transition。
常见错误是写成这样:transition: background-image 0.3s; —— 大部分浏览器根本不支持这个属性过渡,Chrome 甚至会静默忽略。
- 只对
opacity、transform、filter这类可硬件加速且支持插值的属性做过渡才可靠 - 典型做法:两张图叠在一起,用
opacity控制显隐,切换时淡入淡出 - 必须给容器设
background-size: cover或具体值,否则尺寸错乱;background-position也建议明确,避免默认居中导致偏移
:hover 或 class 切换时如何避免闪屏和重排
闪屏常因图片未预加载,新背景图第一次渲染要等下载完成。不是过渡失效,是“从空白到显示”的过程没被覆盖。
- 提前用 CSS 加载新图:
.card::before {content: url(/new.jpg); visibility: hidden; },或 JS 中新建Image实例调用src - 容器必须有固定宽高(不能靠内容撑开),否则
opacity切换时可能触发 layout,造成抖动 - 加
will-change: opacity可提示浏览器提前准备合成层,但别滥用——只在频繁切换的元素上加
用 object-fit 替代 background-image 的过渡限制
如果必须用 <img> 标签(比如 SEO、可访问性要求),object-fit 是更干净的方案,但它本身不可过渡。得靠父容器控制显隐。
立即学习 “ 前端免费学习笔记(深入)”;
- 结构示例:
<div class="img-container"> <img src="a.jpg" class="img-main"> <img src="b.jpg" class="img-alt"> </div> - 关键 CSS:
.img-alt {opacity: 0; transition: opacity 0.3s;},切换时给容器加 class,把.img-mainopacity 设为 0,.img-alt设为 1 -
object-fit: cover必须配width/height,否则 fallback 行为不一致(Safari 和 Firefox 对auto高度处理不同)
IE 和旧版 Safari 下的兼容 fallback
transition 在 IE10+ 和 Safari 6.1+ 支持没问题,但 opacity 动画在 IE10/11 里仍有卡顿,尤其多图并行切换时。
- 不要用
filter: alpha(opacity=xx)—— 它和opacity冲突,且禁用硬件加速 - 简单降级:检测
supports('transition'),不支持就直接切换,不加动画 - 真要保 IE9?只能用 JS 做定时器渐变,但注意 requestAnimationFrame 在 IE9 不可用,得回退到
setTimeout