不能用 :past 和 :future 伪类实现字幕已读/未读样式,因二者无浏览器支持、需元素含 datetime 属性且依赖系统时钟,而字幕状态由用户交互决定;应通过 JS 标记 timeupdate 时机并切换 read/unread 类名,CSS 响应类名控制样式。

不能用 :past 和 :future 伪类实现字幕的已读/未读样式 —— 它们目前不被任何主流浏览器支持,且语义上也不匹配。
为什么 :past 和 :future 不适用于字幕状态
这两个伪类是 CSS4 提案中基于「系统时间与元素时间属性(如 datetime)自动比对」的实验性特性。它们要求元素显式声明时间值(例如 ),且浏览器需解析该时间并与当前系统时间比较后才触发匹配。
字幕(subtitles)通常是一组文本节点或 块,没有内建时间语义;用户“已读”与否是交互行为结果,不是时间戳固有属性。因此:
-
:past不会识别“用户已滚动到此处”或“已点击播放至此” -
:future不会标记“尚未看到的下一句”,除非你给每句都硬编码datetime并依赖系统时钟驱动 —— 这在视频同步场景中既不可靠也不可控 - 截至 2026 年 5 月,
:past和:future在 Chrome、Firefox、Safari 中均无实际支持(MDN 明确标注为 有限可用)
真正可行的字幕已读/未读样式方案
你需要把“已读”状态转化为可由 JS 控制、CSS 可响应的类名切换。核心是:让字幕项具备唯一标识 + JS 标记时机 + CSS 针对类名写样式。
常见做法如下:
- 每条字幕包裹在
Hello中,data-id用于区分顺序 - 监听视频
timeupdate事件,根据当前播放时间戳(video.currentTime)判断哪些字幕已进入可视区间(比如已显示超过 0.5 秒) - 为已过期字幕添加
class="read",未显示/正显示的保留class="unread"或无类 - CSS 中写:
.subtitle.read { opacity: 0.6; color: #666; },.subtitle.unread { font-weight: bold; }
注意:不要依赖 :visited —— 它只对 生效,且受隐私限制(现代浏览器已限制 :visited 可读取的样式范围,无法用于颜色以外的多数视觉变化)。
容易踩的坑:时间判定逻辑太粗糙
字幕不是离散点,而是有起止时间的区间(例如 start=12.3s, end=14.7s)。仅用 currentTime > subtitle.start 判定“已读”会导致:
- 刚进入区间就标为已读,但用户根本没来得及看(字幕闪现)
- 跨多行字幕时,部分行被提前标记,视觉割裂
- 快进跳过时,大量字幕被跳过但未标记,状态错乱
更稳妥的做法是:当 currentTime > subtitle.end + 0.3 时再添加 read 类 —— 留出缓冲,确保字幕已完整展示并退出视区。
真正要做的,是把字幕状态管理权交给 JavaScript,用明确的类名驱动样式,而不是等待一个尚不存在的伪类“自动生效”。浏览器不认的时间语义,就别让它参与渲染决策。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











