aspect-ratio不支持calc(),仅接受字面量分数(如16/9)、小数或auto;变量必须定义为无单位无引号的纯分数字符串,如--ratio: 21/9,且Safari≤15.3会整条忽略该声明。

aspect-ratio 不接受 calc(),变量只能存字面量分数
直接写 aspect-ratio: calc(var(--w) / var(--h)) 会静默失效——所有浏览器都不支持这种写法。该属性只认三种值:字面量分数(如 16/9)、小数(如 1.777)或 auto,不解析任何函数、运算符、引号或单位。
所以变量必须定义成无单位、无空格、无引号的纯分数字符串:
:root { --ratio: 21/9; }.box { aspect-ratio: var(--ratio, 16/9); }
- Safari ≤ 15.3 会整条规则忽略(不是变量没生效,是
aspect-ratio声明被丢弃) - 如果变量未定义且没设 fallback,
var(--ratio, 16/9)中的16/9会兜底,但仅限 Chrome 88+、Firefox 89+、Safari 15.4+ -
--ratio: "16/9"或--ratio: 16/9px都非法,前者是字符串,后者带单位导致解析中断
padding-top + calc() 才能真正做除法运算
想用变量动态算出 padding-top 百分比(比如 9/16 → 56.25%),必须靠 calc() 显式计算,不能把变量当表达式用。
立即学习“前端免费学习笔记(深入)”;
正确姿势是让变量存原始整数宽高,再在 calc() 里做除法:
:root { --aspect-w: 16; --aspect-h: 9; }.video { padding-top: calc((var(--aspect-h) / var(--aspect-w)) * 100%); }
- 括号不能少:
(var(--aspect-h) / var(--aspect-w))必须包起来,否则除法优先级错乱 - 旧版 Safari(≤ 15.6)对
var()参与百分比计算支持不稳定,建议加静态 fallback:padding-top: 56.25%; padding-top: calc((var(--aspect-h) / var(--aspect-w)) * 100%); - HTML 内联覆盖也有效:
<div class="video" style="--aspect-w: 4; --aspect-h: 3;">
Flex/Grid 容器中 aspect-ratio 看似不生效?其实是缺基准
aspect-ratio 不是万能胶,它需要至少一个确定尺寸才能推导另一轴。在 Flex 或 Grid 里,它常“失灵”,其实只是没拿到计算依据。
- Flex 子项没设
flex-basis或width,父容器又没给明确宽度 → 宽度不确定,比例无法触发 - Grid item 的列轨道用
auto或minmax(0, 1fr)→ 列宽未定,aspect-ratio失去参考 - 解决方法不是换方案,而是补约束:给父容器设
width,或给子项加flex: 0 0 auto+ 明确width
容器查询下变量不能自动响应尺寸变化
CSS 变量本身是静态的,clamp(1rem, 5vw, 2rem) 这类写法在声明时就求值完毕,不会随容器尺寸重算。
真要响应容器尺寸,得靠 @container 规则内部重新赋值:
.card { container-type: inline-size; }.card h2 { font-size: var(--title-size, 1.1rem); }@container (min-width: 401px) { .card h2 { --title-size: 1.25rem; } }
- 变量作用域只在当前
@container块内及其后代,不是全局覆盖 - 断点值别重叠(比如
400px和401px),否则边界处可能因渲染精度闪烁 -
var(--title-size, 1.1rem)的 fallback 是必须的,否则未命中任何断点时会回退到unset
最易被忽略的一点:你永远不能指望一个变量既存原始宽高、又参与 aspect-ratio 运算、还能在 padding-top 里自动转百分比——三者技术路径完全不同,得按需选型,混用必踩坑。


















