BEM规范疑问:关联CSS的元素是否都需类名?导航元素如何处理?
关于BEM规范在导航内部元素的正确用法
嘿,这个问题真的是很多刚接触BEM的开发者都会踩的坑,我来帮你梳理清楚~
首先得明确BEM的核心逻辑:它是块(Block)-元素(Element)-修饰符(Modifier)的体系,元素是块的一部分,不能脱离块独立存在;而且官方规范里不推荐多层嵌套的元素命名(也就是header__nav__list这种写法是不符合标准的),因为元素应该直接归属到块,和DOM层级无关。
回到你的场景,我们分两种情况来处理:
情况1:内部元素不需要独立样式/复用
如果你的导航内部ul、li、a只是为了配合header__nav实现基础样式,不需要单独复用,也不需要加特殊修饰符(比如激活状态),那你最初的Less嵌套写法完全符合BEM实践,而且非常推荐:
.header { &__nav { // 导航容器的样式 padding: 1rem; ul { // 列表的样式 list-style: none; margin: 0; padding: 0; display: flex; } li { // 列表项的样式 margin-right: 1.5rem; } a { // 链接的样式 color: #333; text-decoration: none; &:hover { color: #007bff; } } } }
这种写法的好处是:
- 保持HTML结构简洁,不需要给每个小元素都加类名
- 利用Less的嵌套特性,代码结构清晰,和DOM层级对应
- 完全符合BEM的模块化思想,所有样式都归属到
header块下,不会污染全局
情况2:内部元素需要独立样式/修饰符
如果你的导航项需要单独设置样式(比如激活状态、特殊样式的列表项),或者需要在其他地方复用这些元素,那就要给它们单独加类名,但注意不要用多层双下划线,而是把它们作为header块的直接元素:
HTML结构:
<nav class="header__nav" role="navigation"> <ul class="header__nav-list"> <li class="header__nav-item header__nav-item--active"> <a class="header__nav-link" href="">Nav item A</a> </li> <li class="header__nav-item"> <a class="header__nav-link" href="">Nav item B</a> </li> </ul> </nav>
Less写法:
.header { &__nav { padding: 1rem; } &__nav-list { list-style: none; margin: 0; padding: 0; display: flex; } &__nav-item { margin-right: 1.5rem; &--active { font-weight: bold; } } &__nav-link { color: #333; text-decoration: none; &:hover { color: #007bff; } } }
这里的关键是:所有元素都直接归属到header块,用header__xxx的命名,而不是header__nav__xxx——因为在BEM的逻辑里,header__nav-item是header块的一部分,而不是header__nav这个元素的子元素。
总结一下
- 不要为了“符合BEM”而强行给每个元素加类名,BEM的核心是模块化和可维护性,不是冗余的类名
- 多层嵌套的元素命名(比如
header__nav__list)是不符合官方规范的,要避免 - 根据实际需求选择写法:简单场景用嵌套子选择器,复杂场景给需要独立样式的元素加块级元素类名
内容的提问来源于stack exchange,提问作者lampshade
相关产品推荐
相关产品推荐

