
本文详解为何 grid-template-rows: 33% 33% 33% 无法生成等高正方形网格,并提供基于 vh 单位与 aspect-ratio 的可靠解决方案,确保九宫格在任意屏幕尺寸下始终呈现为九个严格等大的正方形。
本文详解为何 grid-template-rows: 33% 33% 33% 无法生成等高正方形网格,并提供基于 vh 单位与 aspect-ratio 的可靠解决方案,确保九宫格在任意屏幕尺寸下始终呈现为九个严格等大的正方形。
在使用 CSS Grid 构建 3×3 网格时,许多开发者会直觉地尝试用百分比定义行列尺寸:
.cont {
display: grid;
grid-template-rows: 33% 33% 33%; /* ❌ 无效:父容器无显式高度 */
grid-template-columns: 33% 33% 33%;
}
但该写法几乎必然失效——根本原因在于:百分比高度(%)在 CSS 中依赖于父容器的明确高度。若 .cont 未设置 height 或 min-height,其高度由内容撑开,此时 33% 无计算基准,浏览器会将其视为 0,最终所有行高度坍缩为内容高度(即“扁平化”)。
✅ 正确解法是脱离对父容器高度的依赖,转而锚定视口单位(vh/vw)并强制子项保持正方形比例:
✅ 推荐方案:vh + aspect-ratio
利用视口高度单位 vh 设置列宽(因网格需等宽等高,列宽决定整体网格尺度),再通过 aspect-ratio: 1 / 1 强制每个单元格为正方形:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.cont {
display: grid;
grid-template-columns: repeat(3, 33.33vh); /* 每列 = 1/3 视口高度 */
width: 100vmax; /* 确保网格宽度不超视口,避免横向溢出 */
height: 100vh; /* 显式设高,使 grid 容器占满视口 */
overflow: hidden;
}
.square {
aspect-ratio: 1 / 1; /* 关键:强制宽高比为 1:1 */
outline: 1px solid #4a5568;
display: flex;
align-items: center;
justify-content: center;
font-size: 1rem;
background-color: #f7fafc;
}
<div class="cont"> <div class="square">1</div> <div class="square">2</div> <div class="square">3</div> <div class="square">4</div> <div class="square">5</div> <div class="square">6</div> <div class="square">7</div> <div class="square">8</div> <div class="square">9</div> </div>
? 为什么用 33.33vh 而非 33.33%?
vh 是绝对单位(1vh = 视口高度的 1%),不依赖父元素高度,可直接用于 grid-template-columns;而 33.33% 在无父高时失效。同时,aspect-ratio 是现代浏览器(Chrome 88+, Firefox 89+, Safari 15.4+)原生支持的属性,无需 JS 或伪元素 hack。
⚠️ 注意事项
- 若需兼容旧版 Safari(
- width: 100vmax 可防止在窄屏(如手机横屏)下因 33.33vh 列宽总和超宽导致横向滚动条;
- 所有 .square 元素自动继承网格轨道尺寸,aspect-ratio 会优先保证正方形,内容居中更直观;
- 避免在 .square 上设置 height 或 width,否则可能覆盖 aspect-ratio 行为。
✅ 总结
实现真正响应式、内容无关的 3×3 正方形网格,核心在于:
- 用 vh 锚定基础尺寸(而非不可靠的 %);
- 用 aspect-ratio 锁定单元格形状(而非手动计算 padding 或 JS 计算);
- 显式声明容器高度(height: 100vh)并控制溢出。
这套方案简洁、语义清晰、无需 JavaScript,且能完美应对动态内容(空单元格或长文本)——这才是现代 CSS Grid 应有的优雅解法。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











