html-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>

你能帮我吗?

aventic asked 2019-10-09T03:11:50Z
3个解决方案
74 votes

关于如何编写BEM类的方法有很多变体,因此请注意,这是多个相互竞争的标准。 它起初是一组宽松的准则。 自发布此答案以来,Yandex大大改进了其官方标准(这是一个很大的进步)。 我使用的BEM版本主要基于Nicolas Gallagher的文章。

在这一点上,我使用“ Atomic OOBEMITLESS”,这实际上只是表示类是模块化和命名空间的,选择器具有较低的特异性,并且状态可以通过允许在CSS预处理器之上缩放CSS的类进行切换 使代码更简洁,更具表现力。

综上所述,我将使用以下BEM标准:

  • 连字符的类名作为块:
    foo-bar
  • 块名,后跟nav__item,后跟元素的带连字符的类名:
    nav
  • 块或元素名称,后跟nav__item,然后是带修饰符的带修饰符的类名:
    navnav.region.region--content

BEM简短格式:nav__item


您的示例中有三个不同的块:

  1. nav__item,其中具有nav元素
  2. nav__item,其中具有nav元素
  3. nav__item,其中包含navnav元素

nav__itemnav块似乎是同一块的变体,可以表示为nav.region.region--content

nav__item块在nav元素上是隐式的,您应该使其明确:

<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>

一旦指定nav__item元素为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>

设置完CSS类后,对所有nav__item元素进行样式设置就很简单:

.nav__item {
    ...styles here...
}

并为内容nav__item元素覆盖这些样式是:

.nav--content__item {
    ...styles here...
}
zzzzBov answered 2019-10-09T03:13:57Z
38 votes

您可能应该看看BEM的常见问题解答。

另一个元素内部的元素的类名称是什么? block__elem1__elem2__elem3

如果我的块具有复杂的结构并且其元素嵌套,该怎么办? 像block__elem1__elem2__elem3这样的CSS类看起来很吓人。   根据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>
Henrique Barcelos answered 2019-10-09T03:14:50Z
3 votes

考虑将修饰符配对成nav_type_content对的想法(块或元素与修饰符名称之间用一个下划线分隔,而其值与另外一个下划线分隔)。

可以将修饰符彼此区分开是有意义的(例如nav_type_contentnav_type_sidebar都与nav页面在页面上的位置有关,但是修饰符设置主题,大小或通过ajax使链接起作用是不同的),以便了解哪些修饰符不能 在一个DOM节点上一起使用。

使用javascript中的key:值对也更方便。

并且有很多使用这种约定的现成组件和工具:[https://github.com/bem/]

tadatuta answered 2019-10-09T03:15:36Z
translate from https://stackoverflow.com:/questions/22566179/bem-block-naming-nesting