ios需同时设置playsinline和webkit-playsinline,安卓微信需x5-playsinline="true";play()须在用户手势同步调用,禁用transform等css及深层嵌套,muted须硬编码。

为什么只写 playsinline 在 iOS 上根本没用
因为 Safari(包括微信 iOS)根本不认单独的 playsinline。它要求必须同时存在 webkit-playsinline,否则直接忽略该请求。iOS 10–12 甚至只认后者,playsinline 是后来才逐步支持的。你写 playsinline="true" 更糟——这是非法写法,HTML5 规范定义它是布尔属性,只看是否存在,不读值;浏览器会把它当自定义属性丢弃。
-
playsinline和webkit-playsinline必须共存,缺一不可 - 不要写
playsinline="true"或playsinline="1",只写playsinline或playsinline="" - Vue/React 中用
v-bind:playsinline或:playsinline动态绑定时,确保渲染结果是无值属性,而非带字符串值
微信安卓端完全不认 playsinline,得用 x5-playsinline
微信安卓用的是腾讯 X5 内核,和 Safari 完全两套体系。playsinline 和 webkit-playsinline 对它基本无效。必须显式加上 x5-playsinline="true"(注意:这里才允许写字符串 "true"),否则哪怕其他条件全满足,也会 fallback 全屏。
- 微信安卓必须写
x5-playsinline="true",不是x5-playsinline - 微信 iOS 同时需要
playsinline、webkit-playsinline和x5-playsinline="true"(三者叠加最稳) - 若视频是 m3u8 流,还要额外移除
x5-video-player-type="h5-page",否则 X5 会强制接管并全屏
JS 主动调用 play() 却跳全屏?大概率是触发上下文不对
即使 HTML 属性全对,play() 被 Safari 拦截后仍会降级全屏。关键不是“有没有调用”,而是“在什么时机、由谁触发”。Safari 只信任直接来自用户手势事件回调里的同步调用。
- 监听
click或touchstart(不用touchend,防误触拦截) - 事件 target 必须是可交互元素(如
button、a),不能是包裹它的div或span - 禁止在
setTimeout、fetch.then、canplay回调里调用play() - 如果用了第三方播放器(如 video.js),确认它透传了
playsInline: true,且禁用了 fullscreen 插件
CSS 和 DOM 结构也会让 playsinline 失效
某些看似无关的样式或嵌套层级,会触发 Safari 的安全回退逻辑,导致内联播放被放弃。这不是 bug,是内核对“页面可控性”的主动判断。
- 避免对
video元素使用transform、scale、rotate等变形 CSS - 微信中
video必须尽量靠近body直接子级,嵌套超过 3 层 div 就可能失效 - 禁用
object-fit: cover+width: 100%组合,X5 内核会判定为“非标准容器”而强制全屏 -
muted必须硬编码在 HTML 标签上,video.muted = true动态设置通常来不及
真正决定 playsinline 是否生效的,从来不是“写了没”,而是 Safari 或 X5 内核是否相信这个播放行为足够安全、可控。所有属性、JS、CSS 都是在回答同一个问题:“这个视频,真的不会脱离我的掌控吗?”——漏掉任何一个环节,答案就是否定的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











