:playing 和 :paused 伪类尚未被任何主流浏览器实现,截至2026年9月Chrome、Firefox、Safari均未支持,需用JavaScript监听play/pause事件切换class,再通过CSS class控制样式。

:playing 和 :paused 伪类目前(2026年9月)**尚未被任何主流浏览器实现**,直接写 video:playing { … } 或 audio:paused { … } 不会产生效果。
为什么你查不到生效的 :playing/:paused 示例
这两个伪类最早出现在 CSS Pseudo-Elements Level 4 草案中,目标是让开发者能基于音视频当前播放状态做纯 CSS 样式响应。但截至今日,Chrome、Firefox、Safari 均未启用该特性——连实验性 flag 都没开放。你在 DevTools 里手动添加这类选择器,样式面板会直接标灰或忽略。
常见误判来源:有人把 :hover + video:hover::after 当成状态联动;也有人混淆了 WebKit 的私有伪类(如 ::-webkit-media-controls-play-button),但那些只控制内部控件样式,不反映真实播放状态。
真正可用的替代方案:用 JS 同步 class 状态
必须靠 JavaScript 检测 video 或 audio 元素的 paused 属性,并手动切换 class。这是目前唯一稳定、跨浏览器的解法:
立即学习“前端免费学习笔记(深入)”;
video.addEventListener('play', () => el.classList.remove('is-paused'))video.addEventListener('pause', () => el.classList.add('is-paused'))- 注意要监听
loadeddata或canplay,避免初始paused === true但还没加载完时误加 class - 别用
setInterval轮询paused,既低效又不准——事件监听足够可靠
CSS 配合 class 实现 UI 联动的关键细节
一旦 JS 把 is-playing / is-paused class 正确打到容器上,CSS 就能干净地响应:
- 按钮图标切换:
.player.is-paused .play-btn::before { content: '▶'; },.player.is-playing .play-btn::before { content: '⏸'; } - 进度条动画启停:
.player.is-paused .progress-fill { animation-play-state: paused; }(注意不是直接作用在video上) - 避免用
element.style.animationPlayState = 'paused'——内联样式优先级高,容易和 class 冲突,统一走 class 控制更可控 - 如果用了
animation-fill-mode: forwards,暂停时不会保留最终态;它只对自然结束有效,和paused无关
真正难的不是写对 class 名,而是确保 JS 监听时机准确、不漏事件(比如用户按空格键触发播放)、且在销毁元素前移除监听器。这些边界情况比 CSS 本身更常导致 UI 不同步。


















