aspect-ratio 不支持直接使用 CSS 变量,因其仅接受字面量值(如 16 / 9),写 var(--ratio) 会被忽略导致容器塌陷;可靠方案是用 padding-top + calc() 动态计算百分比,并通过 @supports 实现渐进增强。

为什么不能直接在 aspect-ratio 里写 CSS 变量?
因为 aspect-ratio 不接受 CSS 自定义属性(--ratio)作为值——它只认字面量,比如 16 / 9 或 1.77。你写 aspect-ratio: var(--ratio),浏览器会直接忽略整条声明,容器塌成一条线。这不是语法错误,而是规范限制:CSS 函数式属性(如 aspect-ratio、grid-template-columns)对变量的支持极有限,目前仅部分函数(如 calc())能安全嵌套 var()。
padding-top 百分比 + var() 是最稳的动态方案
利用 padding-top 的百分比按父宽计算这一特性,把比例逻辑交给 CSS 变量,再用 calc() 换算成百分比值。这是目前兼容性与动态性兼顾的唯一可靠路径。
- 先定义变量:
:root { --aspect-w: 16; --aspect-h: 9; } - 容器样式必须含:
position: relative; width: 100% - 关键计算:
padding-top: calc(var(--aspect-h) / var(--aspect-w) * 100%) - 子
<img alt="如何在CSS中利用变量实现图片占位图的动态长宽比" >必须加position: absolute并撑满,否则不显示
示例:
.placeholder {
position: relative;
width: 100%;
padding-top: calc(var(--aspect-h) / var(--aspect-w) * 100%);
}
.placeholder > img {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
object-fit: cover;
}然后你可以随时切换比例:<div class="placeholder" style="--aspect-w:21; --aspect-h:9"><img src="..." alt="如何在CSS中利用变量实现图片占位图的动态长宽比" ></div>
立即学习“前端免费学习笔记(深入)”;
用 @supports 做渐进增强,别让现代浏览器降级
别用“一套代码通吃”思路。现代浏览器该用 aspect-ratio 就用,老浏览器才 fallback 到 padding-top。靠 @supports 隔离,避免性能浪费和样式冲突。
- 先写现代方案:
.placeholder { aspect-ratio: 16 / 9; width: 100% } - 再用
@supports not (aspect-ratio: 1/1)包裹降级规则 - 注意:Safari 15.4+ 才真正稳定支持
aspect-ratio,iOS 15.2 及更早版本会静默失效 - 不要在降级块里重复写
width: 100%—— 它已在现代块中声明,继承即可
容易被忽略的细节:图片加载前的占位高度必须可预测
动态比例最大的风险不是写法,而是内容未加载时容器高度为 0,导致布局跳动(layout shift)。padding-top 方案天然解决这点,但前提是:变量必须有默认值,且不能依赖 JS 注入。
- 务必在 :root 或组件根元素上设兜底值:
--aspect-w: 4; --aspect-h: 3 - 避免用 JS 动态写
style="--aspect-w:..."后再触发重排 —— 此时 padding 还没生效,用户会看到空白闪一下 - 如果比例来自 API(如 CMS 返回
"ratio": "21:9"),建议服务端或构建时预解析成两个数字,而非前端字符串分割


















