BEM最佳实践疑问:标记交叉的双块场景下方案A是否合规?
好问题!这确实是很多开发者刚接触BEM时会碰到的困惑点——当不同块的职责有交叉时,怎么才能保持BEM的规范并保证代码可维护性。下面针对你的问题逐一分析:
方案A是否符合BEM规范?
答案是不符合。
BEM的核心原则之一是块的独立性,以及元素仅归属一个父块。在方案A中:
<div class="flexblock" > <div class="flexblock__cellelement dateblock"> ... 1.1.2020 ... </div> </div>
flexblock__cellelement是flexblock这个布局块的元素,而dateblock是一个独立的、负责展示日期内容的块。把这两个类放在同一个DOM元素上,相当于让这个元素同时承担了“布局容器”和“内容组件”两个完全不同的职责,会带来两个问题:
- 样式耦合:修改
flexblock的布局样式时,很可能会意外影响dateblock的展示效果;反之修改dateblock的样式时,也可能破坏布局。 - 复用性下降:
dateblock本来应该是可以在任何场景下复用的独立组件,但现在它和flexblock的元素绑定在了一起,无法单独拿出来使用。
方案B的合理性
方案B是符合BEM规范的正确写法:
<div class="flexblock" > <div class="flexblock__cellelement"> <div class="dateblock"> ... 1.1.2020 ... </div> </div> </div>
这里flexblock__cellelement专注于提供布局所需的样式(比如flex属性、间距、对齐方式),dateblock作为独立的块嵌套其中,只负责日期内容的展示样式。两者职责完全分离,样式互不干扰,后续维护时可以单独修改任意一个块的逻辑,不会影响另一个,同时dateblock也能在其他场景下轻松复用。
更优的拓展方案
如果dateblock在flexblock的场景下需要特殊的适配样式(比如调整内边距、对齐方式),推荐用BEM修饰符来处理,而不是直接在flexblock__cellelement里写针对dateblock的样式:
<div class="flexblock" > <div class="flexblock__cellelement"> <div class="dateblock dateblock--flex-item"> ... 1.1.2020 ... </div> </div> </div>
dateblock--flex-item是dateblock的修饰符,专门用来定义它在flex布局场景下的样式变体。这种方式既保留了dateblock的独立性(可以在其他场景下不加修饰符直接使用),又满足了特定布局的需求,完全符合BEM的设计逻辑。
内容的提问来源于stack exchange,提问作者Christian Michael

