无法命名 children 个 BEM 修饰符

Trouble naming children of BEM modifiers

所以我有以下 BEM 类:

.block
.block--modified
.block__child

现在据我所知,大多数人会像这样命名修改后的 .block 的 child:

.block--modified__child

我觉得这是有道理的,但是你有什么理由不能这样命名:

.block__child--modified

我认为这看起来更好并且使修改更加独立/明确,我也喜欢这个因为这样你可以有多个修改的 children 不依赖于被修改的 parent 即

我们可以有 .block.block .block--modified 个元素。

并且两者都可以有 .block__child.block__child--modified,这仍然遵循命名约定,但使 child 元素(修改或未修改)更加灵活。

举个更好的例子,我有以下 类:

.alert
.alert--warning
.alert--urgent

.alert__call-to-action
.alert__call-to-action--warning

我想按如下方式布置我的 HTML:

<div class="alert">
    <button class="alert__call-to-action">
        Action! (No Modifier)
    </button>
</div>

<div class="alert alert-warning">
    <button class="alert__call-to-action alert__call-to-action--warning">
        Action! (Warning Modifier)
    </button>
</div>

<div class="alert alert-urgent">
    <button class="alert__call-to-action alert__call-to-action--warning">
        Action! (Warning Modifier)
    </button>
</div>

所以你会看到我想在 .alert--warning.alert--urgent 中两次 re-use .alert__call-to-action--warning 修饰符,因为无论出于何种原因,样式都是相同的。从我所看到的来看,这是否有意义,它使修饰符更有用?

有没有我们不这样做的原因?抱歉,如果有更好的地方post,请告诉我。

实际上 BEM 方法学说你不应该在元素命名中反映块修饰符。在这种情况下使用嵌套。

参见https://en.bem.info/faq/#why-should-i-avoid-using-nested-selectors

的第二段

这很重要,因为:

  1. 同一block/element
  2. 上可以有相当多的修饰符
  3. 修饰符表示 block/element 的状态,可以在运行时使用 JS 更改。

因此,如果您使用反映在元素命名中的修饰符,它会更难处理。

Which I get that makes sense, but is there a reason you could not name it like this:

.block__child--modified

是的,修饰符需要附加到它修饰的内容上。

如果你有一个块的状态,你将修饰符附加到块:

.message--warning

如果您有一个元素的状态,您可以将修饰符附加到该元素:

.widget__content--expanded

如果您试图将两者混用,则意义会丢失:

//this is a message that is in the warning state
.message--warning

//this is a heading of a message. The heading is in the warning state
.message__heading--warning

So you will see I want to reuse the .alert__call-to-action--warning modifier twice in the .alert--warning and .alert--urgent because for whatever reason the styling is the same.

不要混合搭配修饰符

Does this make sense from what I can see it makes the modifiers much more usable?

您可以使用这种无效的 BEM 用法节省一些 CSS 字节,但这种微优化从来都不是 BEM 的目标。

在我看来,您拥有的不是一组带有修饰符的块。您拥有的是一系列继承自相似基础块的块。

Raw CSS 不允许将这种继承明确化,这很不幸。但是使用预处理器可以。我将在此示例中使用 LESS。

与其定义 .alert.alert--warning.alert--urgent,不如考虑制作三个单独的块:

alert.less
.alert {
  ..default styles..

  &__call-to-action {
    ..default styles..
  }
}
warning.less
@import (reference) 'alert';
.warning {
  .alert;

  ..override styles..

  &__call-to-action {
    ..override styles..
  }
}
urgent.less
@import (reference) 'warning';
.urgent {
  .warning;

  ..override styles..

  &__call-to-action {
    ..override styles..
  }
}

请注意,urgent 是一个 warning,而 warning 是一个 alert。像这样定义 类 允许您在 HTML:

中使用描述性名称
<div class="warning">
  <button class="warning__call-to-action" ...>...</button>
</div>

并允许您充分利用您的样式,因为您只需覆盖少数发生变化的属性。

当然,整个示例依赖于能够使用预处理器来减少您编写的 CSS 量。原始写法 CSS 更冗长。