BEM规范要求元素名必须为block__element格式,用双下划线连接且仅限一级;修饰符用block--modifier或block__element--modifier格式,以双短横线标识状态;块、元素、修饰符语义不可混用,符号不可省略或替换。

元素名必须带双下划线,且只能出现在块名之后
元素(Element)是块的组成部分,语义上不能脱离块独立存在。它的类名格式固定为 block__element,中间是两个连续下划线(__),不是单个或三个。常见错误是写成 block_element 或 block__element__icon——后者属于嵌套元素,BEM明确禁止元素再包含子元素。
实际使用中要注意:
- 元素名不加前缀,
menu__item正确,menu__item__text错误(应改为menu__item-text或另起一个块) - 多个单词的元素名用短横线连接,如
form__submit-button,不是驼峰或下划线 - 元素类必须和块类共存于同一节点或其后代,但不能“跨块”复用,比如
button__icon不能直接用在card块里
修饰符永远用双连字符,且只作用于它所附加的那个节点
修饰符(Modifier)表达的是状态或变体,格式为 block--modifier 或 block__element--modifier,中间是两个连续短横线(--)。关键点在于:它不改变父级或兄弟节点的样式,只影响自己。
典型误用场景:
立即学习“前端免费学习笔记(深入)”;
- 写了
button--large,却指望button__label自动放大——不会,得显式加button__label--large - 在 CSS 中写
.button--disabled .button__icon来控制子元素,这破坏了 BEM 的样式隔离原则 - 把修饰符当布尔属性用,比如
input--required和input--optional同时存在——应该只保留一个有明确语义的修饰符,避免状态冲突
块名、元素名、修饰符名三者命名逻辑完全不同
块名描述组件整体功能(search-form、user-card),元素名描述结构角色(search-form__input、user-card__avatar),修饰符名则聚焦可变特征(--dark、--loading、--disabled)。三者语义不可混用。
容易踩的坑:
- 用
button--primary表示颜色主题,却同时定义button--blue——后者缺乏语义,应统一抽象为--theme-blue或归入设计系统变量 - 把交互状态(
--hover)写进 HTML 类名——这类状态应由伪类:hover处理,修饰符只用于 JS 可控的持久状态 - 元素名里塞修饰符含义,比如
nav__item-active——正确做法是nav__item nav__item--active,保持职责分离
双下划线和双连字符在编译期/运行期都不可省略或替换
它们不是视觉分隔符,而是 BEM 解析器、工具链(如 PostCSS 插件、Sass 函数)识别结构的关键标记。把 __ 写成 _ 或空格,或把 -- 写成 -,会导致自动化提取、文档生成、样式作用域分析全部失效。
尤其注意:
- Sass 中用
@bem混入或&__element语法时,底层依赖严格匹配__和-- - 某些构建工具(如 webpack 的 css-modules 配合 bem-loader)会基于这些符号做作用域哈希,写错就等于样式丢失
- 团队协作中,IDE 的 CSS 类名补全、查找引用等功能也依赖标准符号,非标写法会让同事无法快速定位
__),还是状态性的(该用 --),还是它本该是一个新块?这个问题没想清,符号写对也没用。


















