图片懒加载时占位图怎么处理才不抖动?

小艺菲 阅读 3

我在做图片懒加载,用了一张灰色的占位图,但图片加载完成后页面还是会“抖”一下,布局好像被撑开了。明明设置了宽高,为啥还会这样?

我试过给 img 加 width: 100%; height: auto;,也试过用 CSS 的 aspect-ratio,但效果都不稳定,尤其在移动端。是不是占位图本身尺寸没对齐?

<img src="placeholder.png" data-src="real-image.jpg" alt="" width="300" height="200" />

有没有什么靠谱的做法能彻底避免这种加载时的布局偏移?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
打工人风珍
这个问题很常见,说白了就是浏览器在图片加载前不知道这张图多大,等加载完了突然往里一塞,布局就崩了。

根本原因是你的占位图尺寸和真实图片尺寸没对上,或者根本没预留空间。



第一种做法:用 aspect-ratio 直接锁定比例

这是现在最主流的方案,CSS 的 aspect-ratio 能强制浏览器按比例预留空间:

img {
/* 16:9 比例,宽度300px时高度自动算出来 */
aspect-ratio: 3 / 2;
width: 300px;
height: auto;
object-fit: cover;

/* 占位图用背景色或者用个很小的占位图 */
background: #f0f0f0;

/* 加载时加个过渡效果 */
transition: opacity 0.3s;
}

/* 图片加载完成后隐藏占位效果 */
img.loaded {
opacity: 1;
}


JS 那边这样处理:

const img = new Image();
img.onload = function() {
// 真实图片加载完再替换 src
document.querySelector('img').src = 'real-image.jpg';
document.querySelector('img').classList.add('loaded');
};
img.src = 'real-image.jpg';




第二种做法:用一个透明容器占位

如果你担心 aspect-ratio 在老浏览器上不兼容,可以这样:

.img-wrapper {
/* 强制占位,300x200 */
width: 300px;
height: 200px;
position: relative;
background: #f0f0f0;
}

.img-wrapper img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}


HTML:

<div class="img-wrapper">
<img src="placeholder.png" data-src="real-image.jpg" alt="">
</div>


这样 wrapper 的大小是固定的,不管里面那张图什么时候加载,外部布局都不会动。



第三种做法:占位图尺寸要对齐

如果你坚持用占位图,那占位图的尺寸必须和真实图片完全一致。300x200 的真实图,你就用一张 300x200 的占位图,别用那种很小的灰色小图然后让 CSS 拉伸,拉伸后的尺寸很容易有误差。



移动端注意点

移动端尤其要注意 viewport 宽度变化带来的影响。最好用相对单位:

img {
width: 100%;
aspect-ratio: 3 / 2;
}


或者用 padding-top 的老技巧:

.img-wrapper {
position: relative;
width: 100%;
padding-top: 66.66%; /* 3/2 = 66.66% */
background: #f0f0f0;
}

.img-wrapper img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}


这个 padding-top 技巧兼容性最好,从 IE 时代就能用。



总结一下

你之前试的 width: 100%; height: auto; 其实有问题——auto 意味着高度不确定,浏览器没法提前预留空间。aspect-ratio 就是来解决这个的。

最稳妥的组合是:wrapper + aspect-ratio + 正确的宽高属性,三重保险。实在不行就用 padding-top 那套老方法,兼容性绝对没问题。
点赞
2026-03-10 18:15