Html BEM 块、命名和嵌套
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22566179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BEM block, naming & nesting
提问by aventic
I am trying to wrap my head around BEM naming convention. I am stuck at this. I may misunderstanding something, lets see.
我试图围绕 BEM 命名约定。我被困在这一点上。我可能误解了一些东西,让我们看看。
I have a sidebar nav and a content nav.
我有一个侧边栏导航和一个内容导航。
My sidebar nav looks like this
我的侧边栏导航看起来像这样
<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>
And my content nav looks like this
我的内容导航看起来像这样
<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>
Now I will run into a problem if I style .nav__item, they occur in both my navigations and should not have the same styling. Should I do some nesting here, or am I naming my blocks and elements wrong?
现在,如果我设置 .nav__item 样式,我会遇到问题,它们出现在我的两个导航中并且不应该具有相同的样式。我应该在这里做一些嵌套,还是我的块和元素命名错误?
Nesting example in CSS:
CSS 中的嵌套示例:
.content__nav .nav__item { background: Red; }
Or should I name it like this:
或者我应该这样命名:
<li class="content__nav__item"><a href="#" class="content__nav__link">LINK</a></li>
Can you help?
你能帮我吗?
回答by zzzzBov
There are a number of variants on how to write BEM classes, so be aware that are multiple competing standards. It started as a set of loose guidelines. Since posting this answer, Yandex has significantly overhauled their official standard(it's quite an improvement). The version of BEM I use is based heavily from an article by Nicolas Gallagher.
有许多关于如何编写 BEM 类的变体,因此请注意有多个相互竞争的标准。它开始是一套松散的指导方针。自从发布此答案以来,Yandex 对其官方标准进行了重大改革(这是一个很大的改进)。我使用的 BEM 版本主要基于Nicolas Gallagher 的一篇文章。
At this point I use "Atomic OOBEMITLESS", which is really just a way of saying that classes are modular and namespaced, selectors have low specificity, and states may be toggled with classes which allows CSS to be scaled, on top of a CSS preprocessor to make the code more concise and expressive.
在这一点上,我使用"Atomic OOBEMITLESS",这实际上只是说类是模块化和命名空间的一种方式,选择器具有低特异性,并且状态可以与允许 CSS 缩放的类切换,在 CSS 预处理器之上使代码更加简洁和富有表现力。
All that said, I will be using the following BEM standard:
综上所述,我将使用以下 BEM 标准:
- hyphenated class names as blocks:
foo-bar
- block name followed by
__
followed by hyphenated class names for elements:foo-bar__fizz-buzz
- block or element names followed by
--
followed by hyphenated class names for modifiers:foo-bar--baz
,foo-bar--baz__fizz-buzz
,foo-bar__fizz-buzz--qux
- 将类名连字符作为块:
foo-bar
- 块名后跟
__
元素的带连字符的类名:foo-bar__fizz-buzz
- 块或元素名称后跟
--
修饰符的带连字符的类名称:foo-bar--baz
,foo-bar--baz__fizz-buzz
,foo-bar__fizz-buzz--qux
BEM short form: block-name__element-name--modifier-name
BEM 简写形式: block-name__element-name--modifier-name
You have three different blocks in your examples:
您的示例中有三个不同的块:
sidebar
, which has asidebar__nav
elementcontent
, which has acontent__nav
elementnav
, which hasnav__item
andnav__link
elements
sidebar
,其中有一个sidebar__nav
元素content
,其中有一个content__nav
元素nav
,其中有nav__item
和nav__link
元素
The sidebar
and content
blocks appear to be variations on the same block, and could be represented as .region.region--sidebar
and .region.region--content
.
的sidebar
和content
块似乎是相同的块上的变化,并且可以被表示为.region.region--sidebar
和.region.region--content
。
The nav
block is implicit on the ul
element, and you should make it explicit:
该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>
Once you've specified that the ul
element is a nav
block, it makes sense to have the nav
block be modified:
一旦您指定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>
Once you've set up the CSS classes, styling allnav__item
elements is simply:
一旦你设置了 CSS 类,所有nav__item
元素的样式就很简单:
.nav__item {
...styles here...
}
and overriding those styles for the content nav__item
elements is:
并覆盖内容nav__item
元素的这些样式是:
.nav--content__item {
...styles here...
}
回答by Henrique Barcelos
You should probably have a look at BEM's FAQ.
您可能应该看看BEM 的常见问题解答。
What would be a class name for an element inside another element?
.block__elem1__elem2
?What should I do if my block has a complex structure and its elements are nested? CSS classes like
block__elem1__elem2__elem3
look scaring. According to BEM method, block structure should be flatten; you do not need to reflect nested DOM structure of the block. So, the class names for this case would be:
另一个元素内的元素的类名是什么?
.block__elem1__elem2
?如果我的块具有复杂的结构并且其元素是嵌套的,我该怎么办?CSS 类
block__elem1__elem2__elem3
看起来很吓人。根据边界元法,块结构应该是扁平的;您不需要反映块的嵌套 DOM 结构。因此,这种情况下的类名将是:
.block{}
.block__elem1{}
.block__elem2{}
.block__elem3{}
Whereas the DOM representation of the block may be nested:
而块的 DOM 表示可以嵌套:
<div class='block'>
<div class='block__elem1'>
<div class='block__elem2'>
<div class='block__elem3'></div>
</div>
</div>
</div>
Besides the fact that the classes look much nicer, it makes the elements be dependent on the block only. So, you can easily move them across the block when providing changes to the interface. The changes of the block DOM structure would not need corresponding changes to the CSS code.
除了类看起来更好的事实之外,它还使元素仅依赖于块。因此,在对界面进行更改时,您可以轻松地将它们跨块移动。块 DOM 结构的变化不需要对 CSS 代码进行相应的更改。
<div class='block'>
<div class='block__elem1'>
<div class='block__elem2'></div>
</div>
<div class='block__elem3'></div>
</div>
回答by tadatuta
Consider idea of _key_value
pairs for modifiers (block or element is separated from modifier name with one underscore and its value with another one).
考虑_key_value
修饰符对的想法(块或元素与修饰符名称用一个下划线分隔,其值用另一个下划线分隔)。
That makes sense to distinguish modifiers one from another (e.g. nav_type_content
and nav_type_sidebar
are both about the place where nav
apper on the page but modifiers setting theme, size or making links work via ajax are different) and so to understand which modifiers can't be used together on one DOM-node.
区分修饰符是有意义的(例如nav_type_content
,nav_type_sidebar
两者都nav
与页面上的应用程序有关,但修饰符设置主题、大小或通过 ajax 使链接工作是不同的),因此了解哪些修饰符不能一起使用一个 DOM 节点。
Also it's more convenient to work with key: value pairs in javascript.
此外,在 javascript 中使用 key: value 对也更方便。
And there are quite a lot of ready-made components and tools which uses such convention: https://github.com/bem/
并且有很多现成的组件和工具使用这种约定:https: //github.com/bem/