poster 属性仅在视频 readyState 为 0(HAVE_NOTHING)时显示,是独立于视频内容的静态占位图,非首帧截图;需匹配宽高比、避免 query 参数、确保 MIME 类型正确,并注意 iOS Safari 兼容性问题。

video 标签的 poster 属性到底加载什么时机
poster 是视频首次加载、尚未播放时显示的静态封面图,它不会在视频暂停后自动恢复显示(除非手动重置 currentTime 并调用 load()),也不会替代视频第一帧 —— 它是独立于视频内容的占位图。
常见错误是把 poster 当作“首帧截图”来依赖,结果在某些浏览器(如 Safari)中,视频元数据未加载完成前,poster 会闪一下再被黑屏或首帧覆盖。真正可靠的做法是:确保 poster 图片尺寸与视频宽高比一致,且格式为 WebP 或 JPEG(避免 PNG 透明通道引发渲染差异)。
-
poster只在readyState === 0(HAVE_NOTHING)时生效;一旦进入HAVE_METADATA或更高状态,它就不再显示 - 如果视频设置了
autoplay且静音(muted),部分 Chrome 版本会跳过poster直接播放,此时需用 JS 拦截并手动控制显隐 - 不建议用 base64 编码的
poster,会阻塞 HTML 解析,且无法被浏览器缓存
如何让 poster 图和 video 元素严格对齐不拉伸
默认情况下,<video> 的 object-fit 不影响 poster,只作用于视频画面本身。poster 图由浏览器内部按 background-size: cover 类似逻辑渲染,但不可 CSS 控制 —— 所以必须靠 HTML 属性和容器配合。
最稳妥的方式是:固定 <video> 的宽高(用 width/height 属性或 CSS aspect-ratio),同时确保 poster 图分辨率与视频原始宽高比完全一致(比如 16:9 视频配 1280×720 的 poster)。
立即学习“前端免费学习笔记(深入)”;
- 不要只设
width="100%"而不设height,否则 poster 会被压缩变形 - 用 CSS
aspect-ratio: 16/9+width: 100%是现代方案,但 IE 和旧版 Safari 不支持,需 fallback 到 padding-top 百分比技巧 - 如果 poster 图太小(如 320×180 用于 1920×1080 容器),Chrome 会模糊拉伸;Firefox 则倾向居中裁剪 —— 统一用 ≥ 原始分辨率的图更安全
移动端 iOS Safari 下 poster 不显示的典型原因
iOS Safari 对 poster 的加载策略极严:若视频资源(src)未声明 type,或 poster 图 URL 含查询参数(如 ?v=2),或服务器未返回正确的 Content-Type(必须是 image/jpeg 等),都可能导致 poster 完全不渲染,只留黑块。
调试时打开 Web Inspector → Elements 面板,右键 video 元素 → “Reveal in Elements Panel”,检查 poster 属性值是否被正确解析;再切换到 Network 面板,过滤图片请求,确认 poster 是否 404 或返回 200 但 Content-Type 错误。
- 务必给
<source>标签加上type,例如type="video/mp4",否则 iOS 可能拒绝加载 poster - 避免 poster URL 中带动态参数;如必须加版本号,改用文件名哈希(
cover-abc123.jpg)而非 query string - 确保 Web 服务器对 .jpg/.jpeg/.png/.webp 返回标准 MIME type,Nginx 示例:
types { image/webp webp; }
用 CSS 覆盖 poster 时要注意的兼容性边界
虽然不能直接用 CSS 修改 poster 渲染行为,但可以用伪元素或绝对定位容器模拟封面 —— 这种方式实际可控性更强,尤其适合需要按钮、文字叠加的场景。
关键点在于:必须监听 loadeddata 事件,在视频元数据就绪后隐藏自定义封面,否则会出现双封面闪烁。不要依赖 canplay,它触发太早,可能画面还没解码完成。
- 自定义封面需设置
pointer-events: none,否则会拦截 video 的点击播放行为 - 若 video 设了
controls,自定义封面需避开控制栏区域(通常底部 30px),否则点击控制条会误触封面 - Android Chrome 80+ 对
z-index层级异常敏感,video 元素必须有明确的 stacking context(如设置transform: translateZ(0)),否则自定义封面可能被压在 video 下面
复杂点不在怎么写,而在什么时候删 —— 自定义封面的销毁时机,比创建难得多。一个没清理干净的 loadeddata 监听器,会让后续重新加载视频时封面残留。



















