必须用容器包裹img并设置宽高和background才能实现占位色,单独给img设background-color无效;加载完成通过JS添加类名配合opacity过渡实现平滑显示。
直接给 <img> 元素设 background-color 是无效的——<img> 是替换元素,自身不渲染背景,除非它有宽高且内容(即图片)还没加载出来,但此时浏览器默认只留空或显示缺省图标。真正可靠的方式是用 background 覆盖在容器上。
单独对 <img> 设置 background 不起作用;得用一个 <div> 或其他块级元素包住它,并让该容器承担占位职责:
<div class="img-placeholder"> <img src="photo.jpg" alt="描述"></div>
然后对 .img-placeholder 设背景和尺寸:
width 和 height 必须显式设置(否则容器高度为 0,背景不可见)background-color 或 background-image 写在容器上background-size: cover / contain 可配合伪图使用,但纯色占位只需 background-color
aspect-ratio 替代固定 height(现代浏览器支持),避免布局抖动图片加载完成后,如果容器背景还盖着,会遮挡图片。常见做法是监听 load 事件并移除背景,但更稳妥的是用 CSS 的 background-image + img 叠加,靠层级控制:
立即学习“前端免费学习笔记(深入)”;
background-image: linear-gradient(#f0f0f0, #e0e0e0),而非 background-color,方便后续用 background-image: none 切换<img> 加 display: block; width: 100%; height: 100%,确保填满容器opacity 或 visibility 做淡入效果(注意:直接改 background 无法触发 transition,需用 background-image + transition)示例关键 CSS:
.img-placeholder { width: 300px; height: 200px; background-image: linear-gradient(#f5f5f5, #e5e5e5); background-size: 100% 100%; transition: background-image 0.2s ease;}.img-placeholder img { display: block; width: 100%; height: 100%; opacity: 0; transition: opacity 0.3s ease;}.img-placeholder img.loaded { opacity: 1;}
JS 中只需在 img.onload 时加 loaded 类即可。
老浏览器(如 IE11)不支持 aspect-ratio,也不支持 background-image 的 transition,这时建议:
background-color + 固定宽高作为基础 fallback<img> 自身设 background,它在 Safari/IE 下表现不一致loading="lazy",注意首次进入视口前图片不会触发 load,需结合 IntersectionObserver 补充监听最简健壮方案:容器 + 显式宽高 + background-color + JS 监听 load 后隐藏容器背景或切换类名。复杂动效和渐进增强可以在此基础上叠加,但别一开始就绕过容器这个前提。