Rate组件BEM命名需明确块、元素、状态三要素:rate为块名,rate__item为评分项,rate__item--hover/active为状态修饰符;disabled状态须下沉至子项并禁用交互;半星需rate__item-part细分;JS更新类名应批量操作避免残留。

Rate组件的BEM命名必须反映状态与层级关系
直接套用 .rate 或 .star 会导致样式耦合、难以复用,尤其在嵌套或主题切换时失效。BEM的核心不是“写全”,而是让每个类名能明确回答三个问题:它属于哪个块?处于什么元素?当前是什么状态?
推荐结构:rate 是块名,rate__item 是单个评分项(如一颗星),rate__item--hover 和 rate__item--active 是状态修饰符。注意:rate__item 必须是独立可交互单元,不能把整个评分条当作一个 rate__item —— 否则 hover/active 无法精准响应鼠标位置。
-
rate:只用于最外层容器,不参与交互逻辑 -
rate__item:每个可点击/悬停的星或数字按钮,需有display: inline-block或flex布局支持 -
rate__item--hover和rate__item--active必须用属性选择器或 JS 切换,不能仅靠:hover伪类——否则移动端无 hover 效果且无法保持选中态
如何避免 disabled 状态下交互样式失效
常见错误是给 rate 加 disabled 属性后,只对 rate 设置 opacity: 0.5,但子元素仍响应 hover 或 focus。BEM 要求状态修饰符下沉到具体交互元素。
正确做法:用 rate--disabled 修饰块,并配合 CSS 层叠禁用子项交互:
立即学习“前端免费学习笔记(深入)”;
.rate--disabled .rate__item {
pointer-events: none;
cursor: not-allowed;
}
.rate--disabled .rate__item--hover,
.rate--disabled .rate__item--active {
color: inherit;
background: transparent;
}
注意:pointer-events: none 会阻止所有事件,包括键盘 focus,所以如果需要支持键盘导航(如用 Tab 切换评分),得改用 aria-disabled="true" + 更精细的样式控制,而非单纯依赖 BEM 类名。
半星评分需要额外的元素层级和类名
纯 CSS 实现半星(如 3.5 星)必须拆分视觉表现:通常一个 rate__item 包含两个子元素,分别代表左半和右半。此时不能复用 rate__item 类名,而应引入 rate__item-half 或更明确的 rate__item-part。
- 每个完整星是
<span class="rate__item">,内部包含两个<span class="rate__item-part"> - 激活 3.5 星时,前 3 个
rate__item全亮,第 4 个rate__item的第一个rate__item-part亮,第二个不亮 - 不要用
rate__item--half直接修饰rate__item—— 它不是一种独立状态,而是两个 part 的组合结果
JS 动态更新类名时容易漏掉旧状态
用户从 4 星拖回 2 星,若只加 rate__item--active 到前两颗,第三、四颗上的 rate__item--active 不清除,视觉就会残留。BEM 不解决状态管理逻辑,但类名设计要便于批量操作。
建议在 JS 中统一用 element.classList.toggle() 控制,而不是 add()/remove() 分开调用;同时为所有 rate__item 预设默认态(比如初始不设 --active),再按需添加。
关键点:BEM 类名本身不带逻辑,但命名是否利于批量操作,直接影响维护成本。比如用 rate__item--selected 比 rate__item--on 更易理解意图,也更适配国际化场景(避免 on/off 这类布尔词义歧义)。


















