track元素必须作为video直接子元素且位于source之后、video闭合前,kind、srclang、label、src四属性缺一不可,WebVTT文件首行须为“WEBVTT”加空行、UTF-8无BOM、Content-Type为text/vtt。

track元素必须作为video的直接子元素且位置严格固定
浏览器只在开始标签之后、所有闭合之后、之前这个狭窄区间内解析。放错位置等于没写,而且几乎不报错——video.textTracks.length恒为0,控制台也安静得可怕。
常见失效位置包括:
-
写在前面 → 被忽略 -
包在里或放在外 → 不发起网络请求- 多个
之间插了HTML注释或空行 → Safari 可能中断后续解析- 用JS动态
appendChild插入到已加载完成的中 → 静默失败(DOM已冻结扫描)kind、srclang、label、src 四个属性一个都不能少
浏览器不做任何容错推断。漏掉任意一个,该轨道就不会出现在右键字幕菜单里,不是“不显示”,而是菜单里压根没有选项。
关键细节:
-
kind="subtitles":必须全小写、拼写完整;kind="caption"、kind="subtitles "(末尾空格)均无效 -
srclang:必须是合法 BCP 47 码,如"zh-Hans"、"en-US"、"ja";"chinese"、"zh_CN"、空值全部被忽略 -
label:用户实际看到的菜单名,建议含变体说明,如label="中文(简体)";为空时可能显示(no label),多语言场景下无法区分 -
src:路径需可访问;若跨域,服务端必须返回Access-Control-Allow-Origin: *,否则 Firefox/Edge 静默失败
WebVTT文件格式容错率近乎为零
本身不渲染内容,它只是声明外部轨道;真正决定成败的是.vtt文件。哪怕只错一个字符,Chrome/Firefox 就静默丢弃整条轨道——Network 面板看不到失败请求,控制台不报错,字幕菜单就是空的。合规要点:
- 首行必须是全大写
WEBVTT,后面跟一个空行(不能有BOM,不能是webvtt或WEBVTT) - 时间戳格式必须为
hh:mm:ss.mmm --> hh:mm:ss.mmm,毫秒必须三位(01:23:45.670✅,01:23:45.67❌) - 每段字幕块必须包含编号、时间戳、文本三部分,缺一不可
- 文件编码必须为UTF-8,无BOM
- 服务端必须返回
Content-Type: text/vtt,否则部分浏览器拒绝加载
移动端和默认行为要额外注意
移动端 Safari 要求
带controls属性,否则字幕菜单根本不会出现在控件栏里;iOS 上还可能需要用户手动长按视频唤出菜单。关于
default属性:- 仅允许在一个
上设置,多个会导致行为未定义(多数浏览器只启用第一个) - 设了
default不代表自动显示——它只表示“用户没手动选时的 fallback”,仍需用户在右键菜单中启用字幕功能 - 可通过 JS 检查:
video.textTracks[0].mode === 'showing',但不能靠default属性值来判断当前是否显示
最常被忽略的是服务端响应头和VTT首行格式——这两处出错,整个多语言字幕链就断在源头,连调试入口都没有。
- 多个
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











