aspect-ratio + grid 是当前最稳的九宫格布局方案,无需 js、不依赖图片原始尺寸,且规避 object-fit 失效问题;grid 负责三等分列,aspect-ratio 确保每格宽高比一致,需将 aspect-ratio 设于容器而非 img 上。

直接结论:用 aspect-ratio + grid 是当前最稳的组合,不需要 JS、不依赖图片原始尺寸,且能规避 object-fit 失效的典型陷阱。
为什么 grid + aspect-ratio 能解决九宫格宽高比问题
九宫格本质是「三列等宽、行高随内容或比例变化」的布局。传统方案靠 padding-bottom 配合绝对定位模拟比例,但维护成本高、语义差、嵌套深。而 aspect-ratio 让每个单元格自己“管好自己的高”,grid 负责均匀分列——两者配合后,无论屏幕多宽、图片原始比例如何,每个格子都保持一致宽高比。
常见错误是只给 img 设 object-fit: cover,却没给父容器设 aspect-ratio 或明确高度,结果在竖屏手机上格子被内容撑开、九宫格变成长条。
- 必须把
aspect-ratio加在格子容器(如<div class="item">)上,而不是直接加在 <code><img>上 -
grid-template-columns: repeat(3, 1fr)确保三等分,gap控制间距,无需负 margin - 若需兼容 Safari 14.1 以下或旧版 Android WebView,需用
@supports not (aspect-ratio: 1/1)降级为 padding-bottom 方案 - 图片本身设
width: 100%; height: 100%,确保它占满父容器全部空间 - 再设
object-fit: cover,让图片等比缩放并裁剪填满 - 必须加
overflow: hidden到格子容器上,否则裁剪部分会溢出、破坏网格对齐 - 避免用
max-width: 100%替代width: 100%,后者在 flex/grid 子项中可能失效 - 用
grid-auto-flow: dense+grid-template-rows: repeat(3, 1fr)强制三行,再配合grid-column: span 1控制每个 item 占一格 - 更简单的是加伪元素占位:
.grid::after { content: ""; grid-column: span 9; },但仅适用于固定总数场景 - 如果数据动态加载(比如 7 个、8 个、10 个),建议服务端补空数据或前端用 JS 补
<div class="item placeholder">,CSS 里统一设 <code>visibility: hidden真正麻烦的不是怎么写出来,而是忘记检查格子容器是否塌陷——用 DevTools 看一眼
computed height,如果不是由aspect-ratio推导出来的值,而是0或auto,那所有后续样式都白搭。
如何让每张图都填满格子且不拉伸
格子有了固定宽高比,图片怎么塞进去才不糊、不白边、不偏移?关键在 object-fit 和容器约束的配合顺序。
只写 object-fit: cover 没反应?大概率是图片父容器没尺寸——aspect-ratio 已经给了宽高比,但你还得让图片「知道盒子在哪」。
最后一行不满 9 个时怎么对齐
这是 grid 布局最容易被忽略的细节:默认行为是左对齐,最后一行只有 1 个元素时,它会孤零零贴在最左边,和上面两行不对齐。
解决思路不是改 justify-content,而是利用 grid 的自动填充能力,让空位也参与布局。











