原生 loading="lazy" 在网格布局中会导致塌陷跳动,因其不预留空间,需配合容器宽高比控制和伪元素动画。Grid 项无默认高度,img 加载前为 0×0;aspect-ratio 在父项高度未定义时无效;旧版 Safari 忽略 aspect-ratio;须用 aspect-ratio + position: relative 撑开高度,配合 object-fit 和伪元素占位动画,并注意响应式与 align-items 冲突问题。
原生 loading="lazy" 在网格布局中直接用会塌陷、跳动,必须配合容器级宽高比控制和伪元素动画才可靠。
loading="lazy" 会失效Grid 项默认不设高度,img 加载前是 0×0,loading="lazy" 只推迟请求,不预留空间。结果就是:首屏图片一加载,下面整行卡片突然下移——不是动画问题,是盒模型塌陷。
gap 或 align-items: start,但子项没撑开高度,img 的 aspect-ratio 不生效(因为父项高度未定义)object-fit 在无尺寸约束的容器里完全无效,裁剪和缩放都不可控aspect-ratio,连带让整个占位逻辑归零aspect-ratio + position: relative 撑开网格项高度别指望 Grid 自动算出图片高度,得在每个网格单元(.card 或 .grid-item)上强制撑开比例空间。
aspect-ratio: 16 / 9,并设 position: relative —— 这是伪元素动画和 object-fit 能工作的前提width: 100%; height: auto; object-fit: cover;,且必须包裹在 overflow: hidden 的容器内,否则裁剪溢出@supports not (aspect-ratio: 1) 包裹 padding-top: 56.25% + min-height: 0.01px,否则 padding 百分比被当 0 处理直接对 img 加 opacity 或 transform 动画会从 0×0 尺寸开始播,视觉突兀;正确做法是用 ::before 盖一层动态占位,等图加载完成再切状态。
立即学习“前端免费学习笔记(深入)”;
img 初始设 opacity: 0; position: absolute; inset: 0;,确保它覆盖伪元素但不可见::before 用 linear-gradient 做条纹底纹 + background-position 动画,避免 transform 触发重排load 后加 .loaded 类,仅触发 img 的 opacity: 1 过渡,不改布局visibility: hidden —— 它会让父容器高度塌回 0为不同屏幕写多套 aspect-ratio 值(比如手机 4/3、桌面 16/9)看似合理,实则危险:Grid 项高度由 CSS 计算,断点切换时若 JS 正在加载图片,可能卡在中间比例导致错位。
aspect-ratio: 4 / 3,覆盖多数内容场景;真有极端比例(如竖图),后端返回时额外加 data-aspect="9/16",JS 动态设 style="--aspect-ratio: 9/16"
@media 里改 aspect-ratio —— 浏览器不触发重绘,旧值残留.card 设 min-height: 0,否则 Flex/Grid 可能忽略 aspect-ratio 的高度约束最易被忽略的是:网格项的 min-height 和 align-items 冲突。哪怕写了 aspect-ratio,如果父 Grid 设了 align-items: center,而子项没设 height: 100%,Safari 就会把它压扁——这个细节不调试根本看不出问题。