aspect-ratio 是后备推导而非强制约束:仅当子项宽高完全由布局上下文决定时生效;一旦存在 height/min-height/max-height、grid-auto-rows 固定值或显式 width/flex-basis,即静默失效。

aspect-ratio 不是“强制约束”,而是“后备推导”
浏览器只在子项的宽高完全由布局上下文决定时,才用 aspect-ratio 计算高度。一旦你写了 height、min-height、max-height(哪怕值是 auto),或父容器设了 grid-auto-rows: 200px,它就静默失效。这不是 bug,是设计逻辑:fr 单位分配的是列宽,而 aspect-ratio 需要一个明确的宽度基准来反推高度——如果这个宽度本身被 fr 动态分配、又被其他样式干扰,推导就断了。
fr 本身不控制行高,但会间接破坏比例计算
fr 只管列轨道的宽度分配,对行高零干预。但 Grid 默认 align-items: stretch,会强制每个子项填满所在行的高度;而该行高又由本行中“最高那个子项”决定。结果就是:aspect-ratio 算出的理想高度,被拉伸覆盖了。
- 给网格容器加
align-items: start或align-items: flex-start - 确保子项没写任何
height相关声明(包括min-height: 0) - 绝对不要设
grid-auto-rows为固定像素值(如150px),留空或用minmax(0, 1fr)
真正冲突的不是 fr,而是你写的 width / flex-basis
很多人以为 repeat(3, 1fr) 和 aspect-ratio 冲突,其实不是。真正打架的是你在子项上写的 width: 240px、flex-basis: 200px,或者父容器用了 grid-template-columns: 200px 200px 200px —— 这些显式尺寸会切断 aspect-ratio 所需的“宽度依赖链”。
- 子项必须写
width: 100%,让它严格跟随所在列宽 - 列定义推荐用
repeat(auto-fit, minmax(240px, 1fr)),而非固定像素列 - 避免在子项上设
flex相关属性(如flex: 1),它可能隐式引入flex-basis
移动端和旧 Safari 的兼容性陷阱
aspect-ratio 在 Android WebView、部分安卓原生浏览器、Safari
立即学习“前端免费学习笔记(深入)”;
- 降级方案必须用
padding-tophack:子项设position: relative; height: 0; padding-top: 75%(对应 4:3),内部内容用position: absolute覆盖 - 别指望
@supports (aspect-ratio: 1/1)完全覆盖 —— 某些安卓浏览器报告支持却实际失效 - 若用 JS 动态测量(如
getBoundingClientRect()后设grid-template-columns),务必在requestAnimationFrame回调中执行,否则测到的是未应用aspect-ratio的原始尺寸


















