必须遵循.plyr__*结构,因为plyr的js和css均依赖该bem约定定位真实dom节点;自定义class会导致控制失效、样式不生效及状态不同步。

直接用 .plyr__control 命名按钮、进度条等交互元素,配合 .plyr--fullscreen 这类修饰符表达状态,就能让结构一目了然,避免样式污染和命名冲突。
为什么不用自定义 class 名,而必须遵循 .plyr__* 结构
BEM 在 Plyr 中不是可选项,而是其 CSS 架构的底层约定。所有内置控制组件(如播放按钮、音量滑块、全屏开关)都通过 Shadow DOM 或 JS 动态注入,并绑定到固定 class 名上。如果你写 .my-play-btn 并试图覆盖 ::-webkit-media-controls-play-button,会失败——因为那个伪元素根本不在你写的 HTML 里;而 Plyr 的 DOM 是真实存在的,且只响应它自己定义的 BEM class。
常见错误现象:
- 手动给
<button></button>加class="play",却发现点击无反应 → Plyr 的 JS 只监听.plyr__control[data-plyr="play"] - 用
.video-player__progress覆盖进度条样式,但实际生效的是.plyr__progress→ 类名不匹配,CSS 规则被忽略
.plyr__control 和 .plyr__progress 的语义分工
.plyr__control 是所有可交互控件的通用容器级 class,它本身不决定外观,只表示“这是一个用户能点/拖/切换的东西”。真正区分功能的是它的 data-plyr 属性值:
-
<button class="plyr__control" data-plyr="play"></button>→ 播放/暂停主控 -
<input type="range" class="plyr__control" data-plyr="volume">→ 音量调节器 <div class="plyr__progress"> → 进度条容器(非控件,不可交互,仅展示)<p>注意:<code>.plyr__progress不是.plyr__control的子类,它是独立 Element,用于包裹内部的.plyr__progress__buffer和.plyr__progress__played。混用会导致样式错位或 JS 行为异常。状态类必须用
.plyr--*修饰符,不能硬写is-playingPlyr 通过 JS 动态在根容器(
.plyr)上添加/移除状态类,比如播放时加.plyr--playing,静音时加.plyr--muted。这些类是全局开关,影响整套 UI 的视觉反馈:-
.plyr--playing .plyr__control[data-plyr="play"]::before→ 显示暂停图标 -
.plyr--paused .plyr__control[data-plyr="play"]::before→ 显示播放图标 -
.plyr--fullscreen .plyr__controls→ 控制栏占满全屏高度
如果你自己写
.is-playing并试图控制图标切换,Plyr 的 JS 不会同步这个 class,导致图标状态与实际播放逻辑脱节。自定义扩展控件必须挂载到
.plyr__controls内部,且 class 名保持 BEM 一致性想加一个“倍速选择”下拉菜单?不能丢在
里,也不能用.custom-speed-select这种孤立名:<div class="plyr__controls"> <!-- 原有控件 --> <button class="plyr__control" data-plyr="play"></button> <!-- 自定义控件:必须用 plyr__ 前缀 + 合理 element 名 --> <div class="plyr__speed-control"> <select class="plyr__speed-select"><option value="1">1x</option> <option value="1.5">1.5x</option></select> </div> </div>这样做的关键原因:Plyr 的 CSS 特异性基于
.plyr__controls > *,你的新控件只有在相同层级、同前缀下,才能继承基础间距、对齐、禁用态等默认样式。否则就得重写一整套 reset 规则。最易被忽略的一点:BEM 不是命名游戏,而是约束 DOM 与 CSS 的契约。Plyr 的 class 名一旦改错,JS 就找不到目标节点,CSS 就无法命中,连基本的点击反馈都会消失——这不是样式没生效,是整个控制链断了。
-











