BEM块,命名和嵌套
我试图围绕BEM命名约定来包装我的头。 我被困在这。 我可能会误解一些东西,让我们看看。
我有一个侧边栏导航和内容导航。
我的侧边栏导航看起来像这样
<div class="sidebar"> <ul class="sidebar__nav"> <li class="nav__item"><a href="#" class="nav__link">LINK</a></li> <li class="nav__item"><a href="#" class="nav__link">LINK</a></li> </ul> </div>
而我的内容导航看起来像这样
<div class="content"> <ul class="content__nav"> <li class="nav__item"><a href="#" class="nav__link">LINK</a></li> <li class="nav__item"><a href="#" class="nav__link">LINK</a></li> </ul> </div>
现在我遇到一个问题,如果我风格.nav__item,他们出现在我的导航,不应该有相同的样式。 我应该在这里做一些嵌套,还是我命名我的块和元素是错的?
在CSS中嵌套示例:
.content__nav .nav__item { background: Red; }
或者我应该这样命名:
<li class="content__nav__item"><a href="#" class="content__nav__link">LINK</a></li>
你能帮我吗?
关于如何编写BEM类的方法有很多,所以请注意这是多个竞争标准。 它开始是一套宽松的准则。 自发布这个答案以来, Yandex已经大幅度地改变了他们的官方标准 (这是一个相当大的改进)。 我使用的BEM版本很大程度上来自Nicolas Gallagher的一篇文章 。
在这一点上,我使用“Atomic OOBEMITLESS” ,这实际上只是一种说法,即类是模块化的和名称空间的,select器的特异性较低,状态可以切换到可以缩放CSS的类,在CSS预处理器之上使代码更加简洁和expression。
所有这一切,我将使用以下的BEM标准:
- 用块连字符的类名称:
foo-bar - 块名称后跟
__后跟元素的连字符名称:
foo-bar__fizz-buzz - 块或元素名称后面紧随着修饰符的连字符名称:
foo-bar--baz,foo-bar--baz__fizz-buzz,foo-bar__fizz-buzz--qux
BEM简写forms: block-name__element-name--modifier-name
你的例子中有三个不同的块:
-
sidebar,它有一个sidebar__nav元素 -
content,它有一个content__nav元素 -
nav,它有nav__item和nav__link元素
sidebar和content块似乎是同一个块的变体,可以表示为.region.region--sidebar和.region.region--content 。
nav块隐含在ul元素上,你应该明确:
<ul class="nav"><!-- could be content__nav or sidebar__nav as well if you choose --> <li class="nav__item"><a href="#" class="nav__link">LINK</a></li> <li class="nav__item"><a href="#" class="nav__link">LINK</a></li> </ul>
一旦你指定ul元素是一个nav块,那么修改nav块是有意义的:
<ul class="nav nav--content"> <li class="nav__item nav--content__item"><a href="#" class="nav__link nav--content__link">LINK</a></li> <li class="nav__item nav--content__item"><a href="#" class="nav__link nav--content__link">LINK</a></li> </ul>
一旦你build立了CSS类, 所有 nav__item元素的样式就是简单的:
.nav__item { ...styles here... }
并覆盖这些内容nav__item元素的样式是:
.nav--content__item { ...styles here... }
你应该看看BEM的FAQ 。
什么是另一个元素内的元素的类名?
.block__elem1__elem2?如果我的街区有一个复杂的结构,它的元素是嵌套的,我该怎么办? CSS类像
block__elem1__elem2__elem3看起来吓人。 根据BEM方法,块体结构应平坦; 您不需要反映该块的嵌套DOM结构。 所以,这个例子的类名是:
.block{} .block__elem1{} .block__elem2{} .block__elem3{}
而块的DOM表示可能是嵌套的:
<div class='block'> <div class='block__elem1'> <div class='block__elem2'> <div class='block__elem3'></div> </div> </div> </div>
除了类看起来更好的事实,它使元素只依赖于块。 所以,当对接口进行更改时,您可以轻松地将它们在块中移动。 块DOM结构的变化不需要对CSS代码做相应的改变。
<div class='block'> <div class='block__elem1'> <div class='block__elem2'></div> </div> <div class='block__elem3'></div> </div>
考虑用于修饰符的_key_value对的概念(块或元素与修饰符名称用一个下划线分开,其值与另一个分隔)。
这是有道理的区别修饰符之一(例如, nav_type_content和nav_type_sidebar都是关于在页面上nav_type_content ,但修饰符设置主题,大小或通过AJAX链接工作的地方是不同的),所以了解哪些修饰符不能在一个DOM节点上一起使用。
在javascript中使用键:值对也更方便。
还有很多现成的组件和工具使用这样的约定: https : //github.com/bem/