:playing 和 :paused 不是标准 css 伪类,浏览器完全不支持;应通过 javascript 监听 play、pause、ended 事件,动态切换 class(如 is-playing/is-paused)并配合 css 控制 ui 状态。

:playing 和 :paused 并不是标准 CSS 伪类,**浏览器根本不支持它们**。试图写 .audio-btn:playing { opacity: 0.5; } 或类似规则,会完全无效。
为什么 :playing/:paused 无法使用
CSS 规范中从未定义过 :playing 或 :paused 伪类。W3C 标准里只有 :hover、:focus、:active 等用户交互或 DOM 状态相关伪类,但不包括媒体播放状态——这类状态属于 JavaScript 控制的运行时属性,CSS 无权直接读取。
- 所有主流浏览器(Chrome、Firefox、Safari、Edge)均忽略这两个伪类,开发者工具里也查不到匹配效果
- 部分文章或 Stack Overflow 回答误传该用法,可能混淆了 Web Components 的自定义伪类或实验性提案(如早年 WebKit 曾有非标尝试,早已废弃)
- 即使配合
<video></video>或<audio></audio>元素,原生也不存在该 CSS 接口
真正可行的替代方案:用 class 控制 UI 状态
必须由 JavaScript 检测 HTMLMediaElement 的 paused 属性,并手动切换 class:
const player = document.querySelector('audio');
const btn = document.querySelector('.play-toggle');
<p>function updateButtonState() {
btn.classList.toggle('is-playing', !player.paused);
btn.classList.toggle('is-paused', player.paused);
}</p><p>player.addEventListener('play', updateButtonState);
player.addEventListener('pause', updateButtonState);
player.addEventListener('ended', updateButtonState); // 防止 ended 后仍显示播放中
</p>
- 关键点:监听
play、pause、ended事件,而非轮询player.paused - 不要只依赖
timeupdate——它太频繁,且不能反映暂停/播放切换意图 -
ended必须监听:否则视频播完后paused为 true,但用户预期是“可重新播放”状态,UI 应显示播放图标
配合 CSS 实现视觉反馈
在 CSS 中定义对应 class 的样式,而不是幻想伪类存在:
.play-toggle::before {
content: '▶';
}
<p>.play-toggle.is-playing::before {
content: '⏸';
}</p><p>/<em> 可选:加过渡避免突兀切换 </em>/
.play-toggle::before {
transition: content 0.15s;
}
</p>
- 避免用
display: none切换两个图标元素——增加 DOM 复杂度,且可能触发重排 - 优先用
::before/::after+content切换符号,或用background-image切换 SVG 图标 - 如果要用图片,确保
is-playing和is-pausedclass 在 CSS 中有明确、互斥的样式定义,否则 class 切换可能不生效
最常被忽略的一点:媒体元素初始状态未必是 paused === true。比如自动播放被阻止后,paused 是 true,但尚未触发 pause 事件——所以页面加载后应主动调用一次 updateButtonState(),否则按钮初始状态可能错乱。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











