playsinline 必须硬编码在初始 HTML 中,JS 动态添加无效;iOS WebKit 仅在解析阶段读取,且需与 muted、webkit-playsinline、controls="false" 共存才可能内联播放;微信还需 x5-video-player-type="h5-page"。

playsinline 必须硬编码在 HTML 里,JS 动态加无效
iOS WebKit 只在初始 HTML 解析阶段读取 playsinline,后续用 video.setAttribute('playsinline', '') 或 Vue/React 的响应式绑定(如 :playsinline="true")完全不生效——DOM 已挂载,策略不再重评估。
常见错误:AJAX 加载视频后拼接字符串插入,却忘了把 playsinline 写进字符串里;或用 v-bind 绑定布尔值,结果渲染出 playsinline="true"(这是非法写法,见下一条)。
- 正确写法只有两种:
<video playsinline>或<video playsinline=""> - 绝对不要写成
playsinline="true"或playsinline="1",iOS 直接忽略 - 异步插入的
<video>,必须确保 innerHTML 字符串中已含该属性
iOS 上生效的最小必要属性组合
单独写 playsinline 几乎等于没写。iOS Safari(尤其是 10+)要求它必须和以下三个属性共存才可能内联播放:
-
muted:必须存在,且不能是动态设置的;有声视频首次播放必须由用户手势触发,否则.play()被静默拒绝 -
webkit-playsinline:虽 iOS 10+ 已支持标准属性,但 iOS 12–14 部分机型仍依赖它;漏掉就大概率 fallback 全屏 - 显式声明
controls="false":不是靠 CSSdisplay: none隐藏,而是 HTML 层面禁用控件;否则某些机型点击区域仍会唤起全屏
示例:<video src="v.mp4" playsinline webkit-playsinline muted controls="false"></video>
立即学习“前端免费学习笔记(深入)”;
微信 WebView 还要额外补 x5-video-player-type
微信 iOS 客户端基于 WKWebView,但加了一层拦截逻辑:不认纯标准属性,会主动降级到自己的全屏播放器。只配 playsinline + webkit-playsinline 在微信里大概率失效。
- 必须加
x5-video-player-type="h5-page",这是微信识别“走 H5 内联流程”的关键开关 - 建议同时加
x5-video-orientation="portrait",防止横屏劫持(尤其在 banner 类场景) - 父容器不能有
transform、overflow: hidden或嵌套过深(微信对 DOM 深度有限制) -
<meta name="viewport">必须存在且合法,否则微信可能直接禁用内联能力
autoplay 自动播放能用,但得守规则
想页面加载完自动播?可以,但 iOS 强制要求:必须 muted + autoplay + playsinline 三者同在,缺一不可。即便如此,微信部分版本(如 8.0.29 及更早)仍会拦截无交互的 autoplay。
- 推荐策略:监听
loadeddata或canplaythrough后再调.play(),比load更可靠 - 避免在
setTimeout、API 回调、或mounted生命周期里直接.play()——这不算用户手势上下文 - 如果视频需有声,先以
muted状态启动内联播放,等play事件触发后再在 click/touchend 回调里设video.muted = false
真正稳定的关键不在单个属性,而在于 HTML 初始结构、CSS 布局约束、用户交互时机三者咬合——断掉任何一环,playsinline 就只是个摆设。



















