video标签本身不控制比例,真正起作用的是父容器+CSS渲染规则;必须用aspect-ratio约束容器宽高比(现代浏览器首选),老Safari需@supports降级;video本体设width:100%;height:100%;object-fit:contain/cover;autoplay需同时满足muted、playsinline、用户手势触发三条件。

video 标签本身不控制比例,真正起作用的是它的父容器 + CSS 渲染规则。直接写 width="640" height="360" 或只加 width: 100%,在手机上大概率塌高、controls 挤成一条线、点不动——这不是你代码写错了,是漏掉了宽高比约束这个关键环节。
用 aspect-ratio 控制容器比例(现代浏览器首选)
这是目前最干净、最不易出错的方式,但必须写在 <div> 上,不能直接写在 <video> 标签上。
-
aspect-ratio: 16 / 9表示固定 16:9 比例,浏览器会自动算出高度,你只需指定宽度 - 必须配合
width: 100%,否则容器没宽度,aspect-ratio失效 -
<video>本体设width: 100%; height: 100%,再配object-fit: contain(完整显示)或cover(填满裁边) - 老 Safari(≤15.3)不支持
aspect-ratio,得用@supports降级
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
overflow: hidden;
}
.video-container video {
width: 100%;
height: 100%;
object-fit: contain;
}
<p>@supports not (aspect-ratio: 1 / 1) {
.video-container {
position: relative;
height: 0;
padding-bottom: 56.25%; /<em> 16:9 </em>/
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}为什么 width: 100%; height: auto 常常失效
因为 <video> 是替换元素,它的“固有尺寸”来自视频文件元数据,不是 CSS 能直接 override 的。仅靠 height: auto,浏览器会在父容器没有明确宽高上下文时算出错误高度(比如 0)。
- 父容器必须有可测量宽度(如
max-width: 100%),否则width: 100%没意义 - 小屏下 controls 按像素渲染,缩放后按钮变小、失焦、点不中——这不是样式问题,是 iOS Safari 强制策略
- 未设
playsinline和webkit-playsinline,iOS 点击直接跳全屏,不是 bug - 别给
<video>加margin或border,它们会破坏填满效果
一键切换画面比例的实现逻辑
不能靠 JS 改 video.width 或内联 style,而是切换容器 class,让浏览器重绘整个比例结构。
立即学习“前端免费学习笔记(深入)”;
- 把不同比例封装成独立 class:
.aspect-16x9、.aspect-4x3、.aspect-1x1 - 按钮只负责
container.classList.toggle(),不操作<video>本身 - 确保
container是<video>的**直接父级**,否则aspect-ratio不生效 - 切换后若黑屏或卡顿,先检查是否误删了
width: 100%,或父级有overflow: hidden但没设高度
移动端自动播放与 poster 同步要点
autoplay 在 iOS Safari 上几乎等于“无效”,除非同时满足三个硬性条件:
-
autoplay+muted是基础门槛 - 必须加
playsinline和webkit-playsinline属性,否则强制全屏 - 首次播放必须由用户手势触发(如点击按钮),否则
play()抛DOMException -
poster图片必须和视频原始分辨率同比例裁切,否则用object-fit: cover时首帧模糊
容易被忽略的是:所有比例模式下,object-fit 必须显式声明,不能依赖默认值;否则 poster 和视频帧缩放基准不一致,看起来“错位”。



















