<p>可行,但需用 calc() 计算:padding-top: calc((var(--aspect-h) / var(--aspect-w)) * 100%);直接写 var(--ratio)% 会因字符串替换导致语法错误或兼容性问题。</p>

直接用 CSS 变量控制 padding-top 是可行的,但必须配合 calc() 或预设值,不能在 padding-top 里直接写 var(--ratio) 后跟 %——浏览器会解析失败。
为什么 padding-top: var(--ratio)% 会报错
CSS 变量是字符串替换机制,var(--ratio) 若定义为 56.25,那 var(--ratio)% 实际展开成 56.25%,看似合理;但若变量值带单位(如 56.25%),再拼 % 就变成 56.25%%,语法非法。更麻烦的是:某些浏览器(如旧版 Safari)对变量参与百分比计算支持不稳定,尤其在 padding-top 这种需运行时重算的属性上。
- 错误写法:
:root { --ratio: 56.25; } .video { padding-top: var(--ratio)%; }→ 多数 Chrome 支持,但 Safari 15.6 及更早版本可能忽略 - 安全写法:把计算逻辑移出变量,用
calc()显式表达比例关系,变量只存原始宽高
用 calc() + CSS 变量动态算 padding-top
核心是让变量存整数比(如 --w: 16、--h: 9),再用 calc((var(--h) / var(--w)) * 100%) 算出百分比。这个写法现代浏览器(Chrome 105+、Firefox 110+、Safari 16.4+)都支持,且可复用。
- 必须加括号:
calc((var(--h) / var(--w)) * 100%),否则除法优先级出错 - 变量名建议语义化:
--aspect-w和--aspect-h,避免和布局其他变量冲突 - HTML 中可内联覆盖:
<div class="video" style="--aspect-w: 4; --aspect-h: 3;">
示例:
立即学习“前端免费学习笔记(深入)”;
:root {
--aspect-w: 16;
--aspect-h: 9;
}
<p>.video {
position: relative;
width: 100%;
height: 0;
padding-top: calc((var(--aspect-h) / var(--aspect-w)) * 100%);
}</p><p>.video > video,
.video > iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
兼容性兜底方案:变量 fallback + 媒体查询降级
如果项目需支持 Safari 15.3 或 Android WebView ≤ 4.4,calc() 里的除法可能不被识别。这时不能只靠变量,得提供静态 fallback,并用媒体查询或 JS 补位。
- 静态 fallback 写法:
padding-top: 56.25%; padding-top: calc((var(--aspect-h) / var(--aspect-w)) * 100%);—— 浏览器按顺序解析,忽略不支持的那行 - 移动端竖屏常用 3:4(即
--aspect-w: 3; --aspect-h: 4),对应padding-top: 133.33%,别手算成 133%,小数点后两位更稳 - 若需 IE11 兼容,变量方案完全不可用,必须回归 SCSS 函数或硬编码类名(如
.video-16x9)
容易被忽略的细节:变量作用域与 box-sizing
CSS 变量继承自祖先,但 padding-top 计算结果一旦生效,就和父容器宽度强绑定。如果父容器有 border 或 padding,而没设 box-sizing: border-box,那 width: 100% 会超出预期,导致 padding-top 的基准变小,比例失准。
- 务必在视频容器上加:
box-sizing: border-box - 避免在变量定义处写
!important——它不会提升计算优先级,反而干扰调试 - 调试时用 DevTools 查看 computed
padding-top值,确认是否为最终计算出的百分比(如56.25%),而不是原始变量字符串


















