BEM命名应确保状态类排他性,用notification--success等修饰符驱动状态切换,禁止多状态类共存;状态色通过CSS自定义属性统一管理,避免硬编码;交互态如hover、closing不用BEM修饰符。

通知组件的BEM命名要匹配状态切换逻辑
直接用 notification--success、notification--error 这类修饰符是可行的,但前提是状态变更必须通过添加/移除修饰符类来驱动,而不是靠内联样式或 JS 拼接 class 字符串。BEM 的核心是“语义清晰 + 可预测”,如果 JS 里写成 el.className = 'notification notification--' + type,就容易漏掉基础类或拼错连字符。
推荐做法是固定基础类 notification,所有状态都走 notification--{state} 修饰符,再配合 notification__icon、notification__content 等元素类做局部样式隔离:
<div class="notification notification--warning"> <span class="notification__icon">⚠</span> <span class="notification__content">配置未保存</span> </div>
- 状态类(如
notification--success)只控制背景色、边框色、图标颜色等整体视觉差异 - 元素类(如
notification__icon)不随状态变化,避免重复定义notification__icon--success - 禁用
notification--success notification--error同时存在的情况——CSS 层叠会不可控,JS 必须先 remove 所有状态类再 set 新类
用 CSS 自定义属性统一管理多状态颜色值
硬编码每个状态的颜色(比如 notification--success { background: #d4edda; })会导致维护成本高。更稳的方式是把状态色抽成 CSS 自定义属性,在根节点或组件作用域内定义:
:root {
--notification-success-bg: #d4edda;
--notification-success-border: #c3e6cb;
--notification-error-bg: #f8d7da;
--notification-error-border: #f5c6cb;
}
然后在修饰符中复用:
.notification--success {
background-color: var(--notification-success-bg);
border-color: var(--notification-success-border);
}
.notification--error {
background-color: var(--notification-error-bg);
border-color: var(--notification-error-border);
}
- 新增状态(如
notification--info)只需加一组变量 + 一条规则,不用翻找所有颜色值 - 深色模式适配时,只要重置 :root 下的变量即可,无需改 BEM 类名或结构
- 避免在 JS 中读取
getComputedStyle(el).backgroundColor做逻辑判断——它返回 RGB 值,和 BEM 类名无对应关系
避免用 BEM 表达临时交互态(如 hover / closing)
BEM 的修饰符适合表达「持久性状态」,比如 success / error / warning / info;而 hover、focus、正在关闭动画这些属于「瞬时交互反馈」,不该塞进 BEM 结构里。
- hover 效果直接用
.notification:hover,别写notification--hover - 关闭动效用
notification.is-closing这种非 BEM 的 JS 钩子类(注意:不是notification--closing),方便 CSS 动画触发后移除 - 如果真要用 BEM 表达加载中状态,建议单独拆出
notification--loading,且确保它和 success/error 互斥——loading 是一种独立业务状态,不是交互反馈
JS 切换状态时务必清空旧修饰符
常见错误是直接 element.classList.add('notification--error') 而不先 remove 其他状态类,导致多个 --xxx 同时存在,CSS 层叠顺序难预料。
- 安全写法:
el.className = 'notification notification--' + nextState(简单粗暴) - 或用
classList.replace()(需检查浏览器兼容性) - 更健壮的做法是维护一个状态类白名单数组:
const stateClasses = ['success', 'error', 'warning', 'info'],每次切换前遍历移除 - 切勿依赖
classList.toggle()来切换状态——它无法保证“有且仅有一个状态类”
多状态 BEM 最容易被忽略的点,其实是状态类的排他性约束——它不像普通功能类可以叠加,一旦破坏这个前提,视觉和可维护性都会迅速滑坡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











