图片占位符需兼顾布局稳定、无额外请求、空间撑开及加载失败兼容,纯CSS渐变(如linear-gradient(#eee,#eee))配合background-size、no-repeat和content-box最干净;懒加载须用真实小图占位符+data-src双保险;onerror需防循环且不适用于background-image;动态场景下CSS渐变+aspect-ratio最可控。

图片占位符不是“加个空 <img> 就完事”,关键在于:**不破坏布局、不触发额外请求、能准确撑开空间、且兼容加载失败场景**。纯 CSS 方案最轻量,Holder.js 适合开发阶段快速预览,而懒加载场景必须用 data-src + 占位图双保险。
用 CSS 渐变生成无图占位符
避免引入额外图片资源,又想让容器有明确尺寸和视觉反馈时,linear-gradient 是最干净的方案。它本质是纯色背景,但被当作“图像”处理,可配合 background-size 精确控制显示区域。
-
background: linear-gradient(#eee, #eee)必须写两个相同颜色,否则旧浏览器可能渲染异常 -
background-size要和目标图片宽高一致(比如320px 240px),否则占位区域会拉伸或裁剪 - 一定要加
background-repeat: no-repeat,否则渐变会平铺满整个容器 - 若父容器 padding 影响定位,用
background-origin: content-box让渐变从内容区左上角起始
懒加载中 src 和 data-src 的配合逻辑
占位符在懒加载里不是装饰,而是布局锚点。错误写法如直接把真实 URL 写进 src,会导致图片提前加载;只留空 src="" 则在部分浏览器中会触发 404 请求或破坏高度计算。
- 正确结构:
<img src="placeholder.jpg" class="lazy"> -
placeholder.jpg必须是真实存在的小图(1–2KB),尺寸与目标图一致,且格式支持透明(如 PNG) - 不能用 base64 内联图当占位符——某些 Android WebView 会解析失败,导致空白
- JS 加载真实图后,务必移除
lazy类或重置src,否则 IntersectionObserver 可能重复触发
onerror 替换失败图片的边界条件
当网络中断、路径错误或 CORS 阻止加载时,onerror 是最后一道防线,但它不触发于所有情况——比如跨域图片未设置 crossorigin 属性时,onerror 可能静默失效。
立即学习“前端免费学习笔记(深入)”;
- 基本写法:
<img src="a.jpg" onerror="this.src='fallback.png'"> - 如果 fallback 图也加载失败,需防止无限循环:
onerror="if (this.src !== 'fallback.png') this.src = 'fallback.png';" -
onerror不捕获 CSS background-image 加载失败,那是另一套机制 - 现代项目建议配合
loading="lazy"原生属性使用,但注意 Safari 对onerror+loading="lazy"组合支持不稳定
真正麻烦的从来不是“怎么放一个灰色方块”,而是当图片尺寸动态变化、父容器弹性收缩、或者需要适配暗色模式时,占位符是否还能稳稳撑住布局——这时候纯 CSS 渐变 + aspect-ratio 才是最可控的底牌。



















