用aspect-ratio: 1配合grid-auto-rows: 1fr和repeat(auto-fit, minmax(120px, 1fr))可实现列宽驱动行高的自适应正方形网格,无需JS或padding-top/vw等兼容性差的方案。

直接用 aspect-ratio: 1 + grid-template-columns: repeat(auto-fit, minmax(...)) 就能搞定,不需要 JS,也不依赖视口单位(如 vw)或 padding 技巧。
为什么不用 padding-top 或 vw 单位?
移动端屏幕宽度变化频繁,padding-top: 100% 要求父容器有明确宽度、且子元素必须用 position: relative + 内容绝对定位,结构臃肿;height: 50vw 则会让正方形随视口宽度缩放,但高度可能超出容器、破坏网格对齐。两者在嵌套网格或 flex 容器中极易失效,且无法响应列数变化。
-
padding-top的百分比始终基于父容器宽度,若父容器是 grid track,其宽度不等于内容宽度,计算会错乱 -
vw单位无视父容器限制,比如在 modal 或 scrollable 区域里,正方形可能宽过容器本身 - 两者都无法让「行高自动匹配列宽」,这是网格正方形最核心的约束
用 aspect-ratio + auto-fit 实现真正自适应网格
现代浏览器(Chrome 88+、Firefox 89+、Safari 15.4+)已稳定支持 aspect-ratio,它能让单个网格项强制维持宽高比,再配合 grid-auto-rows: 1fr,浏览器会以列宽为基准反推出行高,实现像素级一致。
- 设置
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)):最小项宽 120px,小屏自动收缩为 1 列,大屏铺开 - 给每个网格项加
aspect-ratio: 1,并确保box-sizing: border-box - 必须设
grid-auto-rows: 1fr,否则行高不会跟随列宽变化(仅设grid-template-rows静态值会失效) -
gap替代 margin,避免边框/内边距撑出溢出(尤其在border存在时)
#grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
grid-auto-rows: 1fr;
gap: 8px;
}
.grid-item {
aspect-ratio: 1;
background: #eee;
border: 1px solid #ccc;
box-sizing: border-box;
}
兼容旧版 Safari(iOS 15.3 及更早)怎么办?
Safari 15.3 不支持 aspect-ratio,但支持 padding-bottom 百分比——此时需退回到伪元素方案,且必须严格控制父容器宽度来源。
- 父容器不能是
display: grid或flex的直接子项(因其宽度不可靠),建议用普通块级容器包裹 - 网格项设
width: 100%+padding-bottom: 100%+position: relative - 内容用
position: absolute填满,否则高度由 padding 占位,内容无法撑开 - 务必加
box-sizing: border-box,否则边框会额外增加尺寸,破坏正方形
这不是理想解,但比 JS 计算更轻量,且只在必要时降级启用。
真正容易被忽略的是:grid-auto-rows: 1fr 这一行。没有它,即使所有项都有 aspect-ratio: 1,行高仍可能按内容撑开或塌陷,导致网格变形——这个属性才是让“列宽驱动行高”的关键开关。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











