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--bazfoo-bar--baz__fizz-buzzfoo-bar__fizz-buzz--qux

BEM简写forms: block-name__element-name--modifier-name


你的例子中有三个不同的块:

  1. sidebar ,它有一个sidebar__nav元素
  2. content ,它有一个content__nav元素
  3. nav ,它有nav__itemnav__link元素

sidebarcontent块似乎是同一个块的变体,可以表示为.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_contentnav_type_sidebar都是关于在页面上nav_type_content ,但修饰符设置主题,大小或通过AJAX链接工作的地方是不同的),所以了解哪些修饰符不能在一个DOM节点上一起使用。

在javascript中使用键:值对也更方便。

还有很多现成的组件和工具使用这样的约定: https : //github.com/bem/

Interesting Posts