track元素本身不渲染DOM节点,无法用CSS直接设置字体或颜色;真正生效的是WebVTT内联类(如)配合::cue伪元素,且仅支持color、font-family、text-shadow等有限样式。

track 元素本身不能用 CSS 直接设置字体或颜色
track 标签只是轨道元数据容器,不渲染任何 DOM 节点——它不生成 <div>、<code><span></span> 或任何可选中元素。浏览器内部用原生控件渲染字幕,你写的 font-family、color、text-shadow 对 <track></track> 标签本身完全无效。
真正起作用的是 WebVTT 文件里的 <c></c>、<b></b>、<i></i>、<u></u> 等内联类,以及 CSS 的 ::cue 伪元素选择器。这两者必须配合使用,缺一不可。
::cue 伪元素是唯一可控的样式入口
所有现代浏览器(Chrome、Firefox、Edge、Safari 15.4+)都支持 ::cue,用于匹配 WebVTT 字幕中任意文本片段(包括带类名的片段)。但注意:它不继承父级 CSS,且只接受有限样式属性。
常见可用样式包括:
立即学习“前端免费学习笔记(深入)”;
-
color、background-color(支持半透明,如rgba(0,0,0,0.7)) -
font-family、font-size、font-weight、text-align -
text-shadow(对提升可读性极关键,尤其深色背景上) -
line-height、white-space、text-decoration -
border和padding在部分浏览器中支持不稳定,慎用
示例:
video::cue {
color: #fff;
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
font-size: 1.2rem;
text-shadow: 0 0 8px rgba(0,0,0,0.8);
background-color: transparent;
}
如果想单独控制某类字幕(比如拼音),需在 VTT 文件中标记:<c.pinyin>Nǐ hǎo</c.pinyin>,再写:
video::cue(.pinyin) {
font-variant: small-caps;
font-size: 0.9em;
}
VTT 文件里必须用 类标记才能被 ::cue 匹配
WebVTT 不是纯文本,它的样式能力依赖内联类语法。没有 <c></c> 包裹,::cue(.xxx) 就找不到目标。
正确写法(subtitles.zh.vtt):
WEBVTT 1 00:00:01.000 --> 00:00:04.500 <c.chinese>你好,欢迎观看</c> 2 00:00:05.000 --> 00:00:08.200 <c.pinyin>Nǐ hǎo, huānyíng guānkàn</c>
错误写法(无类、用 HTML 标签、用 SRT 风格):
- 直接写“你好”,没
<c></c>——::cue(.chinese)完全不生效 - 写
<span class="chinese">你好</span>—— 浏览器忽略,不是合法 VTT 语法 - 混入 SRT 的序号行或空行分隔 —— Chrome 会静默跳过整段
移动端和旧版 Safari 的 ::cue 兼容性陷阱
iOS Safari(尤其是 iOS 16 及更早)对 ::cue 支持极弱:不支持 font-family 自定义、text-shadow 失效、::cue(.class) 基本不识别。Android WebView(WebView 75 之前)甚至不解析 ::cue 规则。
应对策略只有两个:
- 降级用全局
video::cue,只设color和background-color,放弃字体控制 - 彻底放弃原生字幕,用 JS +
textTracks.onchange+track.activeCues手动把字幕内容注入<div id="subtitle-layer">,再用完整 CSS 控制——这是唯一能保证样式 100% 可控的方式 <p>最后提醒:无论怎么调 <code>::cue,都无法改变字幕位置(始终居中底部)、行数(最多两行)、动画(无 fade-in/out)。这些是浏览器硬编码行为,JS 也无法覆盖。



















