全屏时字幕消失是因为浏览器(尤其是Safari)仅将video元素全屏,而track不参与布局;解决方法是让整个播放器容器全屏,并用100dvh、正确VTT格式及退出全屏后再切换语言等措施修复。

全屏时
浏览器(尤其是 Safari)默认只把 元素拉伸进全屏,而 是纯声明性标签,不渲染 DOM,也不参与布局——所以它“没消失”,是压根没被包含进全屏上下文里。真正消失的是你写的自定义控件层,不是字幕轨道本身。
但用户看到的后果是一样的:全屏后字幕没了、控件也没了。解决思路不是修 ,而是让整个播放器容器(含 video + 控件 + 字幕渲染层)一起进全屏。
- 用一个 包住
和所有自定义控件(进度条、按钮等),确保是它的直接子节点仍保留在内部,位置不变(之后、之前) - 全屏触发逻辑改掉:不再调
video.requestFullscreen(),而是调document.getElementById('player-container').requestFullscreen()- 必须保证该容器没有
display: none、visibility: hidden或opacity: 0,否则 Safari 会静默拒绝iOS Safari 全屏后字幕错位或被裁剪
即使容器进了全屏,iOS Safari 的视口行为也会搞乱字幕位置:地址栏收起后
100vh突然变大,导致字幕浮在顶部空白区,或底部被截断。修复方式是监听
fullscreenchange事件,在进入全屏时给容器强设样式:- 添加
position: fixed; top: 0; left: 0; width: 100vw; height: 100dvh; z-index: 9999 - 务必用
100dvh(dynamic viewport height),不是100vh;iOS Safari 对dvh支持已稳定(2024 年起) - 同时给
::cue加一句font-size: clamp(1rem, 4vw, 1.5rem);,避免横竖屏切换时字幕过小或撑出画布
在全屏下不生效的隐藏前提就算结构和全屏逻辑都对了,字幕还是不显示?大概率卡在几个浏览器强制拦截点上:
-
的src必须是真实 HTTP 路径(如/zh.vtt),不能是blob:或data:URL,规范明确不支持,Safari 尤其严格 - VTT 文件首行必须是纯
WEBVTT(无空格、无 BOM、无注释),且后面紧跟一个空行;少这个空行,整个文件被忽略 - 服务器必须返回
Content-Type: text/vtt,用file://协议本地双击打开必然失败(CORS + MIME 双重拦截) - 即使写了
default,用户也得手动在播放器 UI 里点开字幕开关——Safari 不暴露菜单项,除非带controls属性且至少一个有default
动态切换字幕语言时全屏失效
用 JS 切换
textTracks的mode(比如从zh换成en),如果发生在全屏状态下,部分 Safari 版本会触发全屏退出,或新字幕不渲染。这不是 bug,是 Safari 对全屏中 DOM 动态变更的保守策略。稳妥做法:
- 切换前先退出全屏:
document.exitFullscreen(),再改track.mode,最后重新进全屏 - 或者延迟操作:监听
fullscreenchange,等document.fullscreenElement为 null 后再执行切换 - 避免在
timeupdate高频回调里反复设mode,Safari 对此有节流,可能丢帧
最易被忽略的一点:全屏状态下的
::cue样式继承链会被重置,建议把关键样式(如color、background)写在:root或全局 class 里,别只靠局部 container 类控制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











