如何根据BEM命名概念格式化html?

How to format html according to BEM naming concept?

我有愚蠢的代码,这是我将 BEM 命名应用于项目的方法。但我想有些地方不对劲,因为 BEM 规定 elemnts 的元素不应该存在。那要怎么命名呢?

<div class="container">
<div class="profile">
  <p class="profile__message></p>
  <div class="profile__item">
    <div class="profile__item__el profile__item__el-image">
      <a class="thumb"><img></a>
      <div class="profile__item__el-remove"></div>
    </div>
    <span class="profile__item__el profile__item__el-name"></span>
    <span class="profile__item__el profile__item__el-author"></span>
    <span class="profile__item__el profile__item__el-date"></span>
    <div class="profile__item__el-favorite"></div>
  </div>
</div>
</div>

我明白了,我不应该使用单独的 class 'profile__item__el' 因为并非所有元素都属于同一类型,但所有元素都是项目元素,我认为从他们的 class-names,但根据 BEM,它似乎不正确。

我想我可能会朝这个方向走得更多,但即使这样也不是很完美:

<div class="container">
    <div class="profile">
      <p class="profile__message></p>
      <div class="profile__item">
        <div class="profile__attribute profile__image">
          <a class="thumb"><img></a>
          <div class="action--remove"></div>
        </div>
        <span class="profile__attribute profile__name"></span>
        <span class="profile__attribute profile__author"></span>
        <span class="profile__attribute profile__date"></span>
        <div class="action--favorite"></div>
      </div>
    </div>
</div>

"profile__attribute" class 的必要性值得怀疑。只有当您打算将样式应用于所有这些不同的属性时,您才真正需要它。

我认为您误解了 BEM 的 'modifier' 部分的用途。首先,你只使用了一个连字符,但它应该有两个,其次,修饰符更多地用于同一事物的不同变体,比如如果你有一个按钮元素和一个大和小的变体,那么你可以有按钮--large 和 button--small。我会说名称、作者和日期都是单独的元素,而不是同一元素的不同版本。

综上所述,我不太确定 BEM 到底是对还是错,很大程度上取决于个人以及您可能拥有的编码风格指南。

简答。

Every block inside have only element or another block

所以每个元素都有一个 class 就像 block-name__elem-name - 没有额外的 class.

每个块 - 设置命名空间。

要在 BEM 中更改查找阻塞元素,请使用修饰符。

工作原理:html + css - 见下文


BEM也是一个技术栈,自带模板引擎。 所以你不需要写普通的 html - 它会自动编译。

它看起来像什么(bemjson):

{
  block : 'row',
    content : [
      {
          elem : 'col',
          mods : { sw : 4, mw : 2, lw : 2, xlw : 2 },
          content : [
              {
                  block : 'footer', // it's determine parent of element
                  elem : 'age',    // but it's element
                  content : [
                      {
                          block : 'icon',
                          mods : { type : 'some-icon' }
                      }
                  ]
              },
          ]
      },
  ]
}

您可以在 bundle(html) 中看到输出 html:

<div class="row"> // block-namespace
  <div class="row__col row__col_sw_4 row__col_mw_2 row__col_lw_2 row__col_xlw_2"> //elem row__col, then modifiers
    <div class="footer__age"> // element age with forced block footer
      <i class="icon icon_type_some-icon">
        <svg></svg>
      </i>
    </div>
</div>

css 看起来像这样(元素基本上在 2 lvl):

.row // namespace
{
    margin: 0 -7px;

    &__col // element
    {
        padding: 0 7px;
    }
    &__col_p_0 // element with modifier
    {
      padding: 0px;
    }
}

官网文档: https://en.bem.info/methodology/naming-convention/