标签必须嵌在内部且紧贴之后,kind、srclang、label三者缺一不可,webvtt文件首行须为全大写“webvtt”、utf-8无bom编码、时间戳毫秒三位、服务端返回text/vtt mime类型,样式仅支持::cue伪类。

track 标签必须嵌在 video 内部且紧贴 source 后
浏览器只在 <video></video> 开始标签之后、所有 <source></source> 闭合之后的位置解析 <track></track>。放错位置等于没写,而且几乎不报错。
常见错误包括:
-
<track></track>写在<source></source>前面 -
<track></track>放在外面或包在<div> 里 <li>多个 <code><track></track>之间插入 HTML 注释或空行(部分浏览器会中断解析)
正确顺序示例:
<video controls><source src="movie.mp4" type="video/mp4"><track kind="subtitles" srclang="zh" label="中文" src="zh.vtt" default><track kind="subtitles" srclang="en" label="English" src="en.vtt"></track></track></source></video>
kind、srclang、label 三者缺一不可
这三个属性不是“可选增强”,而是浏览器识别轨道并渲染字幕菜单的硬性条件。漏掉任意一个,<track></track> 就不会出现在右键菜单或控件栏中。
-
kind="subtitles":必须是完整单词subtitles,写成subtitle或留空会被忽略 -
srclang:必须是合法 BCP 47 语言码,如zh、en-US、ja;ch或chinese无效 -
label:用户在播放器 UI 中看到的名称;为空时可能显示(no label),多语言场景下无法区分 -
default:只能在一个<track></track>上设置;多个会导致全部失效
WebVTT 文件必须满足四个硬性格式条件
哪怕只漏一个,Chrome/Firefox 就静默失败:不报错、不加载、字幕菜单为空。
- 首行必须是
WEBVTT(全大写,前后无空格,无 BOM) - 文件编码必须是 UTF-8 无 BOM(VS Code 右下角 → “Save with Encoding” → 选 UTF-8)
- 时间戳格式严格:
00:00:01.234 --> 00:00:04.567,毫秒位必须三位,箭头前后各一个空格 - 服务端必须返回
Content-Type: text/vtt;本地用file://协议必失效,得起 HTTP 服务(如python3 -m http.server)
样式控制只能用 ::cue 伪类
字幕渲染在影子 DOM 中,普通 CSS 完全无效,连 class 或 id 都不起作用。
- 必须用
video::cue或全局::cue - 支持的样式极少:仅
color、opacity、font-size、text-shadow、background等 -
margin、display、transform、position全部无效
示例:
video::cue {
color: white;
font-size: 1.2em;
background: rgba(0,0,0,0.7);
}
多语言字幕看似只是加几个 <track></track>,但真正卡住人的,往往是 WebVTT 文件首行少了个大写 V,或是后端没配对 text/vtt MIME 类型——这些地方不报错,也不提示,只让字幕菜单彻底消失。











