::cue伪元素仅作用于已加载激活的WebVTT字幕轨道,要求track.readyState===2、src可访问、首行为WEBVTT,且不支持嵌套选择器或HTML标签样式化。

::cue 伪元素只能作用于 WebVTT 字幕轨道,且仅在 已加载并激活时生效
浏览器不会把 ::cue 应用到纯文本或
下挂载的 ,而且该 track 必须已通过 load() 或自动加载完成、状态为 loaded。常见错误是样式写了半天没反应,结果发现 track 的 src 404 或 CORS 阻止了加载,::cue 根本不触发。 - 检查
track.readyState === 2(loaded)再调试样式 -
必须放在内部,且不能用 js 动态appendChild后再指望样式立刻生效(需等onload) - WebVTT 文件首行必须是
WEBVTT,否则解析失败,::cue失效
::cue 不支持嵌套选择器,所有样式都作用于单个 cue 文本块整体
::cue 是原子级伪元素,无法写成 ::cue b 或 ::cue > span。WebVTT 里的 、、 等 HTML 标签会被解析为内联格式,但它们不是真实 dom 节点,只是渲染提示。你只能对整个 cue 块统一设置字体、颜色、背景,不能单独选中其中加粗部分。
- 想高亮某几个词?WebVTT 里用
或自定义类名(如)没用——::cue(v)不合法,::cue([lang="en-US"])也不支持 - 可用的扩展写法只有
::cue(.highlight),前提是 WebVTT 中用了text,且浏览器支持(chrome ≥ 115、firefox ≥ 119;safari 仍不支持类选择器) - 性能上,
::cue样式会随字幕时间轴频繁重绘,避免用box-shadow或Filter
WebVTT 中的 css 类必须显式声明,且仅限字母数字和连字符
WebVTT 允许在 cue 行末尾加类名,例如:00:00:01.000 --> 00:00:03.000 align:center line:80% class:warning。但这个 class:warning 不会自动变成 HTML 的 class="tuc-19bc10f7-614ed7-0 warning tuc-19bc10f7-614ed7-0",它只是供 ::cue(.warning) 匹配的标识符——而且只认 ASCII 字母、数字、连字符,不支持下划线、中文、空格。
- 错误写法:
class:high-light✅(合法),class:high_light❌(下划线不识别) - 多个类要用空格分隔:
class:warning big-text,对应::cue(.warning, .big-text)(注意逗号是“或”关系) - 类名大小写敏感:
class:Warning≠::cue(.warning) - 如果用 JS 动态注入 WebVTT 内容,需确保类名字符串未被 URL 编码或转义
移动端 Safari 对 ::cue 支持最弱,关键样式建议降级兜底
ios Safari 直到 16.4 才开始支持 ::cue 基础样式(如 color、font-size),且不支持 ::cue(.class)、::cue(::first-line) 等任何扩展。更麻烦的是,它默认把字幕渲染在视频层上方一个独立合成层,z-index 和 transform 完全无效,背景色也常被裁掉。
立即学习“前端免费学习笔记(深入)”;
- 必须兼容 iOS?优先用
::cue设置字体、颜色、文字阴影,放弃背景、圆角、边框 - 测试时真机必跑:模拟器里的 Safari 渲染行为和真机差异极大
- 兜底方案不是 JS 插入 DOM 字幕(破坏可访问性),而是用
+ 原生字幕 ui,再用::cue仅做轻量增强 - 别依赖
::cue实现字幕定位——line、align等 WebVTT 指令本身才是跨平台可靠的定位方式
真正卡住人的往往不是语法,而是 WebVTT 解析时机、类名拼写、iOS 版本碎片,以及你以为改了 CSS 就能立刻看到效果——其实得先让 track 加载成功、字幕时间轴走到那条 cue、浏览器刚好支持这个特性分支。