最简九宫格布局只需三行css:display: grid、grid-template-columns: repeat(3, 1fr)、gap: 8px;用minmax(110px, 1fr)防小屏塌列,aspect-ratio或padding-bottom+absolute保正方形,gap优于margin防错位。

直接写 display: grid + repeat(3, 1fr) 就够了
九宫格不是必须填满9个子项,而是“3列等宽、内容按顺序自动填入”的布局语义。最简实现就是三行 CSS:display: grid、grid-template-columns: repeat(3, 1fr)、gap: 8px。不需要写死 1fr 1fr 1fr,repeat() 更易维护;也不用套 grid-template-rows: repeat(3, 1fr)——除非你真要强制三行固定高,否则让行高由内容撑开更自然。
常见错误是漏掉 gap,转而给每个子项加 margin。这会导致最后一列/行多出一倍外边距,且在字体缩放或 padding 变化时容易错位。记住:gap 是网格容器原生属性,专为行列间隙设计,不参与盒模型计算,稳得多。
子项不够9个时,空白位置留空是正常行为
Grid 按源顺序从左到右、从上到下填充,子项少于9个,剩余格子就是空的——这不是 bug,是 Grid 的默认行为。想强行补满?别用空 <div></div>,那会增加无意义 DOM 节点和可访问性负担。真正需要的是语义化占位:用 grid-template-columns: repeat(3, minmax(110px, 1fr)) 锁定三列轨道,再配 grid-auto-rows: minmax(120px, auto) 控制最小行高。这样即使只有1张图,它也独占第一行三列中的一格,其余轨道仍保留,视觉上仍是“九宫格结构”。
- 别用
auto-fit:子项少时会把剩余列压缩消失,破坏网格感 - 别依赖媒体查询动态改列数:小屏下三列依然可用,关键在单列最小宽度(如
minmax(110px, 1fr))是否抗干扰 - 若需兼容 iOS ≤16.3,
aspect-ratio: 1失效,得降级用padding-bottom: 100%+ 绝对定位
移动端小屏下三列塌成两列?问题出在 1fr 没约束最小宽度
在 iPhone SE(375px 宽)上,repeat(3, 1fr) 算出来的每列宽度可能只有约 109px,一旦图片带标题、字体放大、或加载未完成导致内容宽度略超,浏览器就会判定“放不下”,自动回退为两列。这不是 Grid 不稳定,而是 1fr 本身没设底线。
解决方法是把 1fr 升级为 minmax(110px, 1fr):
-
110px是实测安全值:375px - 2×gap(如 8px)≈ 359px → ÷3 ≈ 119.7px,取整留容错 - 禁用
minmax(33.33%, 1fr):百分比在 Grid 轨道中行为不可控 - 容器别设
padding,改用margin: 0 12px+max-width: calc(100vw - 24px)防溢出
aspect-ratio 和 object-fit 配合才能稳住正方形格子
九宫格常要求格子是正方形,仅靠 width: 100% 不够。现代解法是给每个子项设 aspect-ratio: 1 + width: 100% + height: 100%,但要注意:
- iOS Safari ≤16.3 不支持
aspect-ratio,必须降级:父容器position: relative+padding-bottom: 100%,图片position: absolute填满 - 图片本身用
object-fit: cover,避免拉伸变形;别用height: 120px这类固定高,会截断长文本、无视系统字体缩放 - 加载抖动(“楼梯格”)源于图片高度为 0 → 加载后突然撑开,预设
aspect-ratio或 padding-bottom 就是为防这个
真正难的不是写出九宫格,是在小屏、缩放、加载、兼容性这些真实场景里,让格子不塌、不拉、不闪、不溢出。每一处 minmax、gap、aspect-ratio 的取值,都是被翻车现场逼出来的经验值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











