BEM修饰符是标记组件状态或变体的命名后缀,用双中划线--分隔(如button--disabled),因单中划线-专用于单词连接,双中划线--是规范唯一标识,避免语义混淆与层级冲突。
BEM修饰符用于标记组件状态或变体这一命名后缀用来区分按钮的禁用、成功、加载中等视觉状态,必须紧跟元素名,并以双中划线 -- 分隔,例如 button--disabled 或 card--hovered。之所以不用单中划线,是因为 BEM 规范已有明确区分:单中划线 - 只负责连接单词(如 user-profile),双中划线 -- 才是修饰符唯一合法的标识符;一旦混用,不仅语义会变得混乱,还容易与块或元素层级发生冲突。
button-disabled 则可能被当作新块,进而损害 BEM 层级的可读性 button--primary--disabled 属于非法写法;应改选互斥值,或采用组合类(如同时加 button--primary button--disabled) 这类状态一般只能单选,外观通过切换 class 控制。CSS 的关键做法是让独立规则覆盖基础样式,而不是依靠声明顺序或不断叠加权重。
.button { padding: 8px 16px; border: none; }.button--primary { background: #007bff; color: white; }.button--secondary { background: #6c757d; color: white; }.button--danger { background: #dc3545; color: white; }
.button .button--primary 此类后代选择器,因为它会降低 specificity,并且违背 BEM 原则 :not() 或让 JS 动态删除其他修饰符;互斥关系应由调用方保证,CSS 只定义各个状态的具体外观 .button 基础类中直接定义,不要留空 复合状态需要使用多个修饰符,而不是由单个修饰符完成将它们并列添加在同一个元素上,再由 CSS 通过组合选择器准确命中:
.button--disabled { opacity: 0.5; cursor: not-allowed; }.button--loading::after { content: "…"; margin-left: 4px; }.button--disabled.button--loading { pointer-events: none; }
<button class="button button--disabled button--loading">,使两个修饰符平级共存 .button--disabled.button--loading)比单修饰符拥有更高优先级,适合覆盖特殊的交集行为 .button--disabled .button--loading这种后代选择器,因为它要求 DOM 形成嵌套,违反 BEM 的元素扁平化原则 最容易被忽略的是修饰符语义漂移:同一个 --large 用于按钮时代表尺寸,放在输入框上却表示高度+内边距,久而久之便会造成团队理解不一致。实际的解决方式是:
立即学习前端免费学习笔记(深入);
/<em> --large: only for button & card, affects padding + font-size </em>/ modal--large 和 button--large 即使表现相似,也应作为两套独立规则 button-disabled 这类不正确的写法 在 BEM 中,双中划线并非语法糖,而是状态即契约的视觉锚点;改动一个 -- 便可能造成整个组件的状态逻辑失效。