必须为显式设置html原生width和height属性,因浏览器解析html时css尚未生效,0×0占位导致图片加载后重排并引发cls;仅css宽高无效,aspect-ratio仅为补充且兼容性有限。

引入 CSS 本身不会触发 CLS,但 CSS 的写法和配套的 HTML 结构一旦缺失关键约束,就会让原本“隐形”的布局不稳定性暴露出来——Lighthouse 报告里突然飙升的 CLS,往往不是 CSS 新增了什么,而是它放大了已有漏洞。
为什么 img 没写 width 和 height 属性,CSS 再怎么调也没用?
浏览器解析 HTML 阶段就决定初始布局:如果 <img> 标签没带原生 width 和 height 属性,它的渲染占位就是 0×0 或由内容撑开;等图片异步加载完成,高度突变,下方所有元素被顶下去——这个偏移发生在 layout 阶段,CSS 的 width: 100% 或 aspect-ratio 都来得太晚。
- 必须写成
<img src="x.jpg" style="max-width:90%" style="max-width:90%">,仅靠 CSS 设置无效 -
aspect-ratio: 16/9是好方案,但 Safari 15.4+、Firefox 89+ 才稳定支持,旧版需 fallback 到padding-tophack - 用
srcset+sizes时,仍要配原生宽高,否则浏览器可能先按默认尺寸占位,再调整,造成两次偏移
字体加载策略不当,为什么会被误判为“CSS 引入导致 CLS 升高”?
自定义字体加载慢时,浏览器先用 fallback 字体(如系统字体)渲染文本,等 Web Font 加载完再替换。如果两套字体的 line-height、字宽或 ch 单位行为差异大,段落高度就会突变,把下面内容往下顶——这个过程完全由 @font-face 和 font-display 控制,和普通 CSS 规则无关。
- 禁用
font-display: optional:它可能导致字体反复切换,CLS 更糟 - 优先用
font-display: swap,并配合@font-face { size-adjust: 102%; }减少重排幅度 - 避免在
font-family列表里混用等宽与比例字体(如"Monaco", "Helvetica"),ch/ex行为不一致易引发宽度跳变
动态插入内容前没预留空间,为什么 Lighthouse 总报 body 是主要贡献者?
body 本身不移动,它是所有子元素的容器。当广告、评论、推荐卡片这些 JS 动态插入的内容没有提前占位,插入瞬间就会把原有内容往下顶——Lighthouse 捕捉到的是整个视口范围内的偏移事件,自然归因到 body 上。
- HTML 源码中就要写好占位容器:
<div id="ad-slot" style="min-height: 250px"></div>,高度尽量接近历史均值 - 避免用
visibility: hidden或opacity: 0占位:它们不脱离文档流,但无尺寸,等于没占 - 若必须 JS 插入,优先用
position: absolute或transform: translateY()偏移,不参与文档流布局
真正难处理的不是某条 CSS 规则,而是那些“看不见的尺寸依赖”——图片缺原生宽高、字体缺回退控制、动态模块缺占位结构。这些点一旦漏掉,哪怕加了再多优化类名或 transition,CLS 该跳还是跳。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











