<track>需显式声明且缺一不可:必须作为<video>直接子元素、位于<source>之后,kind="subtitles"、合法srclang、label、可访问的.vtt路径及服务器返回Content-Type: text/vtt,否则字幕静默失效。

<track> 必须显式声明,否则字幕不会被屏幕阅读器识别,也不会出现在播放器字幕菜单里。
为什么 <track> 加了还是没字幕?
最常见原因是 default 属性缺失——浏览器只在有 default 的 <track> 上自动启用字幕;没有它,用户得手动点开字幕开关,而首次播放时根本看不到字幕。
-
srclang和label都不能省:srclang="zh"告诉辅助技术这是中文,label="中文"是播放器界面上显示的名称,缺一不可 - 路径必须可访问:比如
src="sub/cn.vtt",服务器要真能返回text/vttMIME 类型,返回404或application/octet-stream时浏览器静默跳过,控制台不报错 - iOS Safari 对
<track>更敏感:如果视频本身加载失败(比如<source>格式不支持),字幕轨甚至不会尝试请求
<video> 里不能用 alt,该用什么?
alt 只属于 <img>,对 <video> 无效。屏幕阅读器需要的是功能说明或内容摘要,不是替代图。
- 优先用
aria-label:写具体用途,比如aria-label="2026年产品发布会实录(含中英双语字幕)",避免空泛的“视频” - 配合
<figure>+<figcaption>:语义更清晰,且<figcaption>会被自然朗读,适合补充上下文 - 禁用
controls时必须补全 ARIA:自定义按钮要带role="button"、aria-pressed和动态更新的aria-label(如“暂停:当前 42 秒”)
服务器响应头不匹配,前端怎么写都没用
所有 <source> 和 <track> 的 type 或 MIME 判断,都发生在 HTML 解析阶段,不发请求、不报错、不警告——只静默跳过。
立即学习“前端免费学习笔记(深入)”;
-
<source type="video/mp4">要求服务端返回Content-Type: video/mp4,返回application/octet-stream就算路径对也失败 -
<track kind="subtitles" type="text/vtt">实际不用写type(规范不强制),但服务器必须返回Content-Type: text/vtt - 验证方式很简单:用
curl -I https://yoursite.com/cn.vtt或看 Network 面板的 Response Headers,确认字段值完全一致 - 本地开发时用
file://协议会绕过 MIME 检查,导致“本地能跑,上线就黑屏”,务必起 HTTP 服务测试
真正卡住项目的,从来不是怎么写 <track>,而是服务器有没有配对的 Content-Type 响应头、字幕文件是否真能被 HTTP GET 到——这两处出问题,所有标签和属性都白搭。



















