图片加载占位需三步:预留空间(aspect-ratio或padding-bottom)、视觉占位(css背景渐变或base64缩略图)、平滑切换(data-src+load/error监听+opacity过渡),缺一不可。

让图片在加载过程中显示占位图,核心是三件事:提前预留空间、视觉上有内容可看、真实图到位后平滑切换。不能只靠 src 切换或单纯加个 loading 动画——那样容易白屏、跳动、失败留空。
给容器设固定宽高比,防止布局抖动
浏览器渲染时,没尺寸的 <img> 标签不占空间,图片一加载,文字和下方内容就会突然下移。这不是样式问题,是盒模型缺失导致的强制重排。
- 现代写法优先用
aspect-ratio: 16/9配合width: 100%,比如:<img src="placeholder.jpg" style="max-width:90%"> - Safari 15.3 及更早版本不支持
aspect-ratio,可用回退方案:height: 0; padding-bottom: 56.25%; position: relative;,再把<img>绝对定位填满 - 别用
min-height或max-width替代——它们不参与初始布局计算,压不住塌陷
用 CSS 背景做静态占位,不依赖网络
外部占位图服务(如 placeholder.com)一旦离线或 DNS 失败,就直接变白块。纯 CSS 方案更稳,且无额外请求。
- 最简可用:
.img-wrapper { background: linear-gradient(#e0e0e0, #f5f5f5); background-size: cover; }
渐变比纯色更能暗示“这里有图”,不是空内容 - 要模糊缩略图效果(LQIP),把 base64 图嵌进
background-image,控制在 2–3KB 内
例如:background-image: url('data:image/jpeg;base64,/9j/...'); - 若真实图比例和容器不一致,慎用
background-position: center;推荐background-size: contain; background-repeat: no-repeat
用 data-src + JS 控制加载与显隐
只改 opacity 不够——加载失败时用户看到的是透明空框。必须监听 load 和 error 两个事件,确保终态可见。
- HTML 结构示例:
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="内容">
这个 1×1 GIF 占位图体积小、无解码开销 - JS 监听逻辑(推荐用 class 切换,便于 CSS 维护):
img.addEventListener('load', () => img.classList.add('loaded'));img.addEventListener('error', () => {<br> img.classList.add('loaded');<br> img.src = '/fallback.png';<br>}); - CSS 过渡建议:
img { opacity: 0; transition: opacity .3s; }<br>img.loaded { opacity: 1; }
懒加载场景要额外注意
loading="lazy" 只控制加载时机,不提供占位能力。它和占位是两套事,必须配合使用,否则滚动到图片前会先闪白块。
- 懒加载仍需占位图 + 宽高比 +
data-src,不能只写loading="lazy" - 响应式图片要同步迁移
data-srcset和data-sizes,否则高 DPR 设备可能加载错尺寸 - 如果用了
<picture></picture>,<source></source>标签也得逐个处理data-srcset
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











