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/