aspect-ratio与固定比例布局。
aspect-ratio 与固定比例布局说明该属性只在盒子一个方向为 auto 时生效,同时写死宽高会被忽略;新项目应优先用 aspect-ratio,老项目用 @supports 降级,仅在兼容旧浏览器时回退 padding-top 百分比;
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 兜底,就能既简洁又稳。
转载请注明出处,版权归原作者所有。
正式会员






