图片必须带 width 和 height 属性以防布局抖动;video 悬停跳动需初始透明边框占位;模态框开启时用 margin-right 补滚动条宽度;feedback 容器须预置 html 中并用 visibility 隐藏。

img 标签必须带 width 和 height 属性
不写 width 和 height 是布局抖动(CLS)最常见源头。浏览器解析 HTML 时若没这两个属性,就无法推算图片固有宽高比,初始占位为 0×0 或行内默认尺寸,等图片加载完成才重排——下方文字、按钮全被顶下去。
即使你写了 max-width: 100% 或 aspect-ratio: 16/9,旧版 Safari 和部分 Chrome 首帧仍可能 fallback 到无占位状态。CSS 补救不如 HTML 原生声明可靠。
-
<img src="a.jpg">→ 抖动高发 -
<img src="a.jpg" style="max-width:90%" style="max-width:90%">→ 浏览器首帧即知尺寸,稳 - SVG 同理:必须带
viewBox,最好也显式设width/height,否则某些场景会按 300×150 渲染再缩放
video 元素 hover 移位本质是盒模型突变
悬停时位置跳动,几乎从不因为 :hover 本身,而是触发了边框、内边距或伪元素的动态添加,导致元素尺寸变化,进而引发重排。
典型错误:.video-container:hover video { border: 2px solid #007bff; } —— 初始无边框,hover 加 2px 实色边框,宽度+4px,父容器若没设 box-sizing: border-box 或预留空间,必然跳。
- 正确做法:初始用
border: 2px solid transparent占位,hover 只改border-color - 确保
video设display: block,避免行内换行间隙干扰 - 父容器需有明确宽高,或至少设
min-height,防止内容撑开后重排
模态框打开时 body 宽度突变的修复逻辑
模态框一开,body 滚动条消失,页面可用宽度瞬间增大,右侧内容左移——这不是样式问题,是结构级宽度重计算。
靠 overflow: hidden 简单禁用滚动条,只会让抖动更明显。真正要做的,是把滚动条“腾出来的空间”用 margin-right 补回去。
- 先读当前
document.body.offsetWidth - 设
document.body.style.overflow = 'hidden' - 再读一次
offsetWidth,差值就是滚动条宽度 - 用
document.body.style.marginRight = '${scrollBarWidth}px'锁住宽度 - 关闭模态框时,记得清掉
marginRight和overflow
feedback 提示容器不能 JS 动态插入
表单校验失败后才 appendChild 一个提示 div,等于在流式布局里硬塞新节点——下方所有内容立刻下移,不是动画抖,是结构塌陷。
这个容器必须作为 input 的紧邻兄弟节点,硬编码在 HTML 里。隐藏方式只能用 visibility: hidden; height: 0; overflow: hidden,绝不能用 display: none —— 后者会让父容器高度塌缩,后续动画位移可能被截断。
- 若父容器是 flex/grid,给 feedback 区设
min-height: 1.2em,保底占位不破坏行高 - 移动端加
touch-action: none和临时禁用pointer-events,防抖动期间误触 - 每次
blur校验前,先清空aria-invalid、class和 feedback 文本;失败后三者必须同步更新
offsetHeight、getBoundingClientRect() —— 这类抖动不会报错,只拖慢主线程,且极难定位。结构层面能控的,务必控死;JS 层面的读写顺序,得靠 getBoundingClientRect 批量读 + style.cssText 批量写来兜底。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











