poster属性是视频加载时的占位图,仅在元数据加载完成前显示;chrome v78+会在loadedmetadata后隐藏,safari则持续显示至播放,跨浏览器需结合css背景与dom覆盖方案。

video 标签的 poster 属性只在视频未播放时生效
它不是“封面图”而是“加载占位图”:浏览器加载 <video></video> 元素但尚未开始播放、且尚未解码出第一帧时,会显示 poster 指定的图片。一旦视频元数据加载完成(触发 loadedmetadata 事件),哪怕还没播放,部分浏览器(如 Chrome)就会隐藏 poster,露出黑底或首帧——这常被误认为“失效”。
常见错误现象:
- 设置了
poster,但页面一打开就看到黑屏,不是预期图片 - 用 JS 动态设置
video.poster = 'xxx.jpg',但没效果 - 图片路径正确,但控制台报 404,实际路径却没错(可能是相对路径解析错位)
实操建议:
-
poster必须是静态属性,写在 HTML 标签里最可靠:<video poster="cover.jpg"></video> - 路径优先用相对于 HTML 文件的路径,避免用相对于 JS 执行位置的路径
- 确保图片尺寸与
video的宽高一致或按比例缩放,否则可能被拉伸/裁剪(CSSobject-fit可控,但poster本身不支持)
Chrome 和 Safari 对 poster 的行为差异明显
Chrome 从 v78 起,在 readyState >= 2(即已加载元数据)后自动隐藏 poster;Safari 则坚持显示到用户点击播放或调用 play() 前。这意味着:同一段代码,在 Safari 看起来“始终有封面”,在 Chrome 却“一闪就没了”。
如果你需要跨浏览器统一呈现封面(比如做自定义播放按钮层),不能只依赖 poster:
- 给
<video></video>添加style="background: url(cover.jpg) center/cover",作为 CSS 备用底图 - 监听
loadedmetadata事件,在 Chrome 中手动补一层 DOM 覆盖(如绝对定位的<img>),并在play或timeupdate触发后移除 - 避免用
preload="none"—— 它会让poster显示更久,但首次播放延迟明显,且 iOS Safari 可能忽略该属性
动态切换 poster 的可行方式只有重载 src
直接赋值 video.poster = newUrl 在多数浏览器中无效(DOM 属性更新不触发重绘)。真正能刷新封面的,只有让浏览器重新解析视频资源:
- 先清空
src:video.src = '' - 再设新
poster:video.poster = 'new-cover.jpg' - 最后恢复
src:video.src = 'video.mp4',并调用video.load()
注意:这个过程会中断当前播放、清空缓冲,且触发一次完整的加载流程。如果只是想“暂停时显示不同封面”,不如用 CSS 背景 + JS 控制显隐更轻量。
移动端(尤其 iOS)对 poster 尺寸和格式敏感
iOS Safari 要求 poster 图片宽度 ≥ 640px,否则可能降级为黑屏;同时拒绝 WebP 格式(即使声明了 type="image/webp")。错误示例:poster="thumb.webp" 在 iPhone 上静默失败。
实操建议:
- 统一用 JPG 或 PNG,尺寸至少 640×360(16:9)或适配设备视口宽度
- 不要压缩到过小(低于 20KB),iOS 有时会因解码失败而跳过渲染
- 真机测试必做:模拟器里的
poster行为和真机常不一致
最易被忽略的一点:如果视频本身带关键帧(IDR frame)且首帧视觉信息足够,iOS 会优先用首帧替代 poster,哪怕你写了 poster 属性——这时换图不如优化视频编码参数(如强制首帧为关键帧)来得稳定。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











