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

直接用 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;"> <p>示例:</p> <pre class="brush:php;toolbar:false;">: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%; } </p></pre> <h3>兼容性兜底方案:变量 fallback + 媒体查询降级</h3> <p>如果项目需支持 Safari 15.3 或 Android WebView ≤ 4.4,<code>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-sizingCSS 变量继承自祖先,但
padding-top计算结果一旦生效,就和父容器宽度强绑定。如果父容器有border或padding,而没设box-sizing: border-box,那width: 100%会超出预期,导致padding-top的基准变小,比例失准。- 务必在视频容器上加:
box-sizing: border-box - 避免在变量定义处写
!important——它不会提升计算优先级,反而干扰调试 - 调试时用 DevTools 查看 computed
padding-top值,确认是否为最终计算出的百分比(如56.25%),而不是原始变量字符串
- 静态 fallback 写法:











