为什么我的页面布局偏移导致CLS很高?

司空雨路 阅读 42

我最近用Lighthouse测性能,发现CLS(累积布局偏移)特别高,明明没加什么动态内容啊。仔细看发现是图片加载时撑开了布局,但我已经给img加了width和height属性了,怎么还是有偏移?

这是我的HTML片段:

<div class="card">
  <img src="banner.jpg" width="300" height="200" alt="宣传图" />
  <p>这里是介绍文字</p>
</div>

是不是光写width/height还不够?需要配合CSS设置display: block或者aspect-ratio吗?

我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
闲人亚会
你遇到的问题很常见。HTML属性width和height只是给浏览器一个提示,并不会自动转换成CSS来预留空间。图片加载前,浏览器根本不知道要留多少空白,加载完成后突然撑开,CLS就上去了。

解决办法很简单,用CSS把宽高写死:

.card img {
width: 300px;
height: 200px;
}


或者用aspect-ratio更灵活一点:

.card img {
width: 100%;
height: auto;
aspect-ratio: 3 / 2;
}


这两种写法都能让浏览器在图片加载前就知道该留多大空间,布局就不会跳了。

display: block其实不是关键,它主要是消除img底部的间隙,和CLS关系不大。你之前只写了HTML属性,浏览器可不管那个,它只看CSS里有没有明确的空间声明。

另外提醒一下,如果你用了响应式图片(srcset),上面这些CSS最好也配合object-fit一起用,防止图片被拉伸变形。
点赞 1
2026-03-11 13:11
长孙俊荣
你这问题我太熟悉了,很多人以为加了 widthheight 就万事大吉,其实浏览器识别的是渲染尺寸,不是物理像素值。
Lighthouse 里 CLS 高,大概率是因为图片加载时还没渲染出尺寸,或者图片实际宽高比和你写的 width="300" height="200" 不一致——比如图片本身是 1920×1080,但你硬写成 300×200,浏览器会按比例压缩,但这个压缩动作可能发生在 layout 阶段之后,导致文字被往下顶。

调试看看:打开 DevTools 的 Performance 面板,勾选 Layout,录一段加载过程,重点看有没有图片加载后触发的重排(Reflow)。
另外注意 img 默认是 inline 元素,虽然加了宽高,但某些字体或行高下可能还有 baseline 对齐的坑。
稳妥做法是:

1. 保持 widthheight 属性值与图片真实宽高一致(或者至少比例一致)
2. CSS 里加 display: blockobject-fit: cover(如果你用了容器包裹)
3. 更推荐直接用 aspect-ratio,比如:

.card img {
width: 100%;
height: auto;
aspect-ratio: 300 / 200;
}


或者 HTML 属性里直接写:

<img src="banner.jpg" width="300" height="200" loading="lazy" />


注意:如果图片是响应式的(比如容器宽度不定),就别写死宽高像素值,改用比例,或者用 CSS 的 aspect-ratio + max-width: 100%
我之前踩过坑:写死 300×200,在手机上图片被压缩成 300px 宽,但高度没跟着算,结果图片加载完把下方内容顶下去 80px,CLS 直接爆表。
点赞 3
2026-02-27 13:03