九宫格Flex布局关键在于小屏稳定撑满且不换行错位:需显式设flex-wrap: wrap、flex-direction: row,用flex-basis而非width控制格子尺寸,并配合gap或calc减间隙防错位。

Flex实现九宫格的容器基础设置
关键不是“怎么排成三行三列”,而是让display: flex在小屏下稳定撑满、不换行错位。移动端默认视口宽度窄,flex-wrap: wrap必须显式写上,否则子项强行单行挤在一起,溢出或缩成一条线。
-
flex-direction: row(默认可省,但建议写明,避免被重置) -
flex-wrap: wrap(不加这个,九宫格在 iPhone 上大概率只显示前 3 个) -
justify-content: space-between或space-around——别用center,会导致左右留白不均 - 容器需设固定宽高或
aspect-ratio: 1,否则高度塌陷,看不出“格”
每个格子的尺寸控制:用flex-basis而不是width
直接写 width: 33.33% 在 Flex 容器里容易被压缩或拉伸,尤其当内容有图片、文字时。真正可控的是 flex-basis,它定义主轴上的初始大小,再配合 flex-grow: 0 和 flex-shrink: 0 锁死尺寸。
- 单个格子设
flex: 0 0 calc(33.333% - 2px)(减去间隙,防 wrap 错位) - 间隙用
gap: 4px最干净;若要兼容老 iOS(margin +box-sizing: border-box - 别依赖
width+float混用,Flex 下 float 会被忽略
iOS Safari 的gap兼容问题怎么绕
gap 在 iOS 11.2+ 才支持,低于这个版本会完全失效,九宫格变成一坨贴边堆叠。不能靠「用户升级系统」解决,得降级处理。
- 检测是否支持:
@supports (gap: 4px)写现代写法,里面用gap - 不支持时 fallback 到
margin:给子项加margin-right: 4px; margin-bottom: 4px,再用:nth-child(3n)清除右 margin - 注意
margin会扩大容器总宽,父容器加overflow: hidden防横向滚动条
点击区域小、响应迟钝?别忘了touch-action和min-height
九宫格常用来做图标入口,但很多团队只设了 width 和 height,没考虑触摸设备的最小点击面积。iOS Safari 对小于 44×44px 的可点区域会延迟响应或误判为滑动。
立即学习“前端免费学习笔记(深入)”;
- 每个格子至少设
min-height: 44px(哪怕内容只有图标) - 加
touch-action: manipulation,告诉浏览器“这是按钮,别等双击或缩放” - 如果格子里是
<a></a>或<button></button>,确保它们 display 是 block,且不被父级overflow: hidden剪掉
实际最麻烦的不是布局,是 iOS 旧版 gap 失效后 margin 计算漏掉最后一行的 bottom margin,导致底部缺一条缝。这个得手动用 :nth-last-child(-n+3) 补,但别硬背,先打开 Safari 开发者工具真机调试一遍再说。










