九宫格用 flex 布局必须设 flex-wrap: wrap,否则9个子项会强行挤在一行;推荐用 gap 控制间距、aspect-ratio 保持正方形、outline 或 box-shadow 实现高亮,移动端用视口单位适配。

九宫格用 display: flex 必须设为 flex-wrap: wrap
纯 flex-direction: row 默认不换行,9个格子会强行挤在一行,超出容器也不折行。必须显式加 flex-wrap: wrap,否则后续所有对齐、间距的调整都白搭。
常见错误是只设 justify-content: space-between 就以为能均分,结果发现第4个格子直接跳到第二行开头——那是因为没换行,浏览器把它当“溢出内容”处理了。
实操建议:
- 容器设
display: flex+flex-wrap: wrap+width(比如300px) - 每个格子设固定宽高,推荐用
flex: 0 0 calc(33.333% - 2px)(留出间隙余量) - 避免用
justify-content: space-around,它对首尾项额外加半倍间隔,九宫格边缘会留空不对称
格子间距统一用 gap,别用 margin
gap 是 Flexbox 原生支持的行列间距属性,IE 不支持,但现代项目基本可放心用。用 margin 模拟间隙会导致:首行第一格左边、末行最后一格右边多出冗余 margin;响应式缩放时 margin 不随容器等比缩放,容易错位。
示例写法:
.grid {
display: flex;
flex-wrap: wrap;
gap: 8px; /* 行与列间隙都是 8px */
width: 300px;
}
<p>.grid > div {
flex: 0 0 calc(33.333% - 8px); /<em> 宽度 = 1/3容器 - 1份gap </em>/
aspect-ratio: 1; /<em> 保持正方形,替代 height </em>/
}</p>
注意:calc(33.333% - 8px) 中的 8px 来自 gap,不是随意写的——因为 gap 在每两个格子之间生效,每行3格就有2个横向 gap,总占用 2 × 8px,所以单格宽度要减去 8px(不是 16px),这是初学者最常算错的地方。
抽奖高亮效果优先用 outline 或 box-shadow,少动 border
抽奖过程中需要动态标记“当前选中格”,如果用 border,会改变格子尺寸(触发重排),导致整个九宫格抖动;而 outline 和 box-shadow 是绘制层叠加,不影响布局。
推荐方案:
- 用
outline: 3px solid #ff6b35,简单、无偏移、支持outline-offset微调位置 - 或用
box-shadow: 0 0 0 3px #ff6b35,兼容性更好,且可叠加内阴影表现“按下”态 - 避免给高亮格加
transform: scale(1.05),虽视觉突出但会挤压邻格,破坏网格结构
移动端适配关键在 aspect-ratio 和视口单位
九宫格在手机上不能靠固定 px 宽高,否则小屏溢出或过大。核心是让格子随屏幕缩放仍保持正方形,并填满安全宽度。
实操要点:
- 容器宽度用
min(90vw, 400px),兼顾小屏不溢出、大屏不过大 - 格子用
aspect-ratio: 1+flex-basis: calc(33.333% - 8px),比写死height更健壮 - 如果需兼容旧版 Safari(
aspect-ratio不支持),改用padding-top: 100%+position: relative+ 绝对定位内容,但复杂度陡增
真正麻烦的是抽奖逻辑和动画节奏——CSS 只管“长什么样”,但“转几圈停哪格”“是否防连点”“中奖反馈延迟”这些,得靠 JS 控制 class 切换时机,而且 transition 的 timing-function 得调成 cubic-bezier(.3,1.2,.3,1) 这类非线性才像真实转盘感。这个层面,Flex 布局只是画布,别指望它替你做决策。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











