aspect-ratio 不能直接用于 元素,因其是替换元素,宽高比由视频元数据决定,CSS 该属性对其无效;必须包裹容器并配合 @supports 降级、object-fit 和全屏事件监听确保兼容性。

aspect-ratio 能用,但不能直接写在 <video></video> 上——浏览器会忽略它,视频高度塌陷或拉伸。必须套一层容器,且要处理 Safari、微信 iOS、全屏跳转等真实环境里的断裂点。
为什么 <video></video> 本身不能设 aspect-ratio
<video></video> 是替换元素(replaced element),它的宽高比由视频元数据决定,CSS 的 aspect-ratio 对其无效。你写 video { aspect-ratio: 16 / 9 },现代浏览器会直接忽略,导致容器高度为 0 或被撑开变形。
常见错误现象包括:
- 视频压成一条横线(height 计算为 0)
- 宽度正常但高度没按比例撑开,上下留大片空白
- 加了
width="640" height="360"属性后,CSS 完全失效
务必移除 <video></video> 标签上的 width 和 height 属性,否则它们会覆盖 CSS 控制逻辑。
立即学习“前端免费学习笔记(深入)”;
Bootstrap 5 的 .ratio 类怎么配 <video></video>
Bootstrap 5 的 .ratio 是为容器设计的,不是给 <video></video> 自身用的。正确结构是:
<div class="ratio ratio-16x9">
<video class="w-100 h-100 object-fit-cover">
<source src="demo.mp4" type="video/mp4">
</video>
</div>关键点:
-
.ratio必须作用于外层<div>,不能加在 <code><video></video>上 -
.ratio-16x9提供aspect-ratio: 16 / 9+ fallbackpadding-bottom: 56.25% -
<video></video>必须加w-100 h-100(即width: 100%; height: 100%) -
object-fit-cover防止拉伸变形;若要完整显示,改用object-fit-contain - 把父容器从
display: flex改成display: grid - 或加
align-items: start阻止 flex item 被拉伸 - 微信 iOS v8.0.4x 虽识别
aspect-ratio,但渲染异常,建议 UA 判断后统一降级为padding-top方案 - 调用
gcd(3840, 2160) === 240 - 得
3840/240 = 16,2160/240 = 9,拼成"16/9" - 避免
Math.round(w / h * 100) / 100这类近似,精度损失会导致窄屏下出现 1px 黑边
注意:Bootstrap 5.3+ 才原生支持 object-fit-* 工具类,旧版需手动补 CSS 或内联 style="object-fit: cover"。
Safari 15.4–16.3 和微信 iOS 的兼容性坑
Safari 15.4 到 16.3 在 display: flex 父容器里会完全忽略 .ratio 的 aspect-ratio,导致高度计算为 auto 或 0。
验证方法:打开 Safari 开发者工具 → 检查元素 → 查看 computed height 是否异常。
临时解法:
更稳做法是用 @supports (aspect-ratio: 1 / 1) 包裹新写法,外部提供 padding-top + position: relative 降级。
动态宽高比和全屏时的结构切换
从 API 拿到视频尺寸(如 { width: 3840, height: 2160 })时,不能直接算小数比:3840 / 2160 = 1.7777777777777777,某些浏览器解析失败。
永远用最简整数比:
移动端全屏时,iOS Safari 会让 <video></video> 脱离文档流,外层 .ratio 容器高度归零。必须监听 webkitbeginfullscreen / webkitendfullscreen 事件,临时移除 .ratio,设 position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;退出后再恢复。这点在桌面模拟器测不出来,真机必验。


















