aspect-ratio与固定比例布局。
`aspect-ratio` 是目前给盒子锁定宽高比最省事的方式:一个声明就能替代过去 `padding-top` 撑百分比的老套路,新项目应该优先用它,老项目再用 `@supports` 做降级兜底。
aspect-ratio 的生效规则:只有一个维度是 auto 时才起作用
结论:`aspect-ratio` 只在盒子有一个方向是「自动尺寸」时才决定另一边,如果同时写死了 `width` 和 `height`,这个属性会被完全忽略。
写法很简单,斜杠两边可以是数字也可以是长度值:
.card-cover { width: 100%; aspect-ratio: 16 / 9; }
.avatar { width: 48px; aspect-ratio: 1; } /* 等价 1 / 1 */
还有一种是 `auto` 关键字:`aspect-ratio: auto 16 / 9`。它的含义是——对 `<img>`、`<video>` 这类替换元素优先用文件自身的固有比例,其他普通盒子才套用 16/9。做图片占位骨架时这个写法很实用,能避免图片没加载完时布局高度塌成 0。
另外注意:`aspect-ratio` 算的是盒子的首选比例,不是硬约束。一旦内容比计算结果更高,盒子会被撑开,比例就破了,后面「坑」一节会讲怎么处理。
三种固定比例方案的取舍
结论:能用 `aspect-ratio` 就别用 padding 百分比;只有在必须兼容 2021 年前的老浏览器时才回退。
- `aspect-ratio`(首选):一行搞定,内容参与正常文档流,不需要绝对定位,可读性最好。
- padding-top 百分比技巧(兜底):`padding` 的百分比是按包含块宽度算的,所以 `padding-top: 56.25%` 正好等于 16:9。老写法长这样:
.ratio { position: relative; height: 0; padding-top: 56.25%; }
.ratio > * { position: absolute; inset: 0; }
它的代价是内容必须绝对定位或再套一层包裹,且盒子无法被内容自然撑高——做全屏轮播图还行,做内容卡片就很别扭。
- 依赖图片自身固有比例:`img { width: 100%; height: auto; }` 对单张图最省事,但多图网格里各图高度不一,会出现高低错落,需要配 `object-fit: cover` 加固定比例容器才整齐。
常见坑:flex 拉伸、grid 拉伸和内容溢出
结论:`aspect-ratio` 失效十有八九不是属性写错,而是被 flex/grid 的默认拉伸或最小尺寸规则覆盖了。
- Grid 里失效:网格项默认 `align-items: stretch`,会被拉伸到行高,比例形同虚设。解决:给该项加 `align-self: start`,或容器上设 `align-items: start`。
- Flex 里被内容顶高:flex 子项默认 `min-height: auto`,内部文字多一点就顶破比例。解决:加 `min-height: 0`,或给盒子 `overflow: hidden`。
- 被 `min-height` 覆盖:写了 `aspect-ratio: 1` 又写 `min-height: 200px`,窄屏下盒子会被 min-height 拉成竖长条。要么去掉 min-height,要么用媒体查询分别控制。
- 和 `height: 100%` 打架:父级没有确定高度时 `height: 100%` 会失效,此时比例仍按 auto 计算,容易出现「改了半天没反应」的错觉,先确认父链高度是否可解析。
实战组合:图片网格与视频容器
结论:`aspect-ratio` 负责框,`object-fit` 负责内容适配,两者配合才是完整的固定比例布局。
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
.grid img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover; /* 裁切填满,不变形 */
border-radius: 6px;
}
想给响应式图片换不同裁切比例,可以在媒体查询里直接改 `aspect-ratio` 的值,比如窄屏用 `1`(方图)、宽屏用 `16 / 9`,比重新算 padding 百分比直观得多。视频容器同理,`iframe { width: 100%; aspect-ratio: 16 / 9; }` 即可,不再需要那层 `position: relative` 的壳。
降级写法
结论:老浏览器不支持时,布局会退化成「按内容自适应高度」,不会崩,但会跳动,所以建议显式降级。
.cover { position: relative; height: 0; padding-top: 56.25%; overflow: hidden; }
.cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
@supports (aspect-ratio: 1 / 1) {
.cover { height: auto; padding-top: 0; aspect-ratio: 16 / 9; }
.cover img { position: static; }
}
用 `@supports` 把新写法单独放进去,老浏览器走 padding 方案、新浏览器走原生方案,两边都不会出现布局塌陷。
一句话收束:固定比例布局的正解是「一个维度自动 + `aspect-ratio` + `object-fit`」,注意规避 flex/grid 的默认拉伸与内容溢出,再用 `@supports` 保留一层 padding 兜底,就能既简洁又稳。
转载请注明出处,版权归原作者所有。
星耀SVIP
管理员
黑卡会员





