惯用的 CSS BEM 嵌套

Idiomatic CSS BEM nesting

我真的很喜欢 BEM 背后的想法,但有时我很难决定如何为我正在做的事情建模。例如:

<ul class="events">
  <li class="event">

    <!-- We could go this way... -->

    <div class="event__meta event__meta--title"></div>
    <div class="event__meta event__meta--date"></div>
    <div class="event__meta event__meta--location"></div>

    <!-- Or should event__meta be event-meta? -->

    <div class="event-meta event-meta--title"></div>
    <div class="event-meta event-meta--date"></div>
    <div class="event-meta event-meta--location"></div>

    <!-- So now, should event__meta--title be  event-meta__title? -->
    <!-- Or maybe event__title? -->
    <!-- Or should event-meta wrap them all? -->

    <div class="event-meta">
      <div class="event__title"></div>
    </div>
    <div class="event-meta">
      <div class="event__date"></div>
    </div>
    <div class="event-meta">
      <div class="event__location"></div>
    </div>

    <!-- Should event-meta revert to event__meta now? -->
    <!-- Should event__title and friends now be event-meta__title, etc.? -->

  </li>
</ul>

处理这种情况的惯用 BEM 方法是什么?

What to do about grandchild selectors?

我看到你的问题是决定如何处理孙子选择器,这是一些人首先避免使用 BEM 的常见原因。希望这个 post 能让人们更容易理解所讨论的前端开发方法。


让我们用下面的例子来说明这一点:

<ul class="events">
  <li class="event">
    <div class="event__meta">
      <div class="event__meta__title"></div>
      <div class="event__meta__date"></div>
      <div class="event__meta__location"></div>
    </div>
  </li>
</ul>

在这个例子中,您可以看到命名可能会失控,最终会出现越来越多的嵌套组件。


避免多元素级命名。

您应该在选择器名称中使用一次元素级别,请记住 BEM 代表 Block__Element--Modifier 而不是 Block__Element__Element--Modifier。


BEM 命名并不严格依赖于 DOM

无论后代元素嵌套多少层,都应该遵循块级的命名约定。 BEM 旨在让开发人员更轻松地识别不同组件与其顶级组件 Block 之间的关系。

也就是说,前面的例子看起来像这样:

<ul class="events">
  <li class="event">
    <div class="event__meta">
      <div class="event__title"></div>
      <div class="event__date"></div>
      <div class="event__location"></div>
    </div>
  </li>
</ul>

最后一个例子:

JSFIDDLE DEMO


代码片段:

* {
  box-sizing: border-box;
}
body {
  margin: 0;
}
.main-content {
  border-top: 20px solid #7B1FA2;
  background-color: #9C27B0;
  padding: 2em 1em;
}
.events {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
}
.event {
  background: #fafafa;
  border-radius: 2px;
  margin: 2em 1em;
  position: relative;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
  transition: box-shadow 0.3s cubic-bezier(.25, .8, .25, 1);
}
.event:hover {
  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.event--is-first {
  order: -1;
}
.event__meta {
  padding: 2em;
  font-family: 'Copse', serif;
}
.event__title,
.event__date,
.event__location {
  margin: 0.5em 0;
}
.event__title {
  font-size: 2em;
}
.event__title--big {
  font-size: 3em;
}
.event__date {
  font-size: 1.2em;
}
.event__date--underlined {
  text-decoration: underline;
}
.event__location {
  font-size: 1.5em;
}
.event__location--right {
  text-align: right;
}
<div class="main-content">
  <ul class="events">
    <li class="event">
      <div class="event__meta">
        <div class="event__title">
          Festival of life and death traditions
        </div>
        <div class="event__date">
          From October 30th to November 2nd
        </div>
        <div class="event__location">
          Cancún, México
        </div>
      </div>
    </li>
    <li class="event">
      <div class="event__meta">
        <div class="event__title event__title--big">
          Sacred Mayan Journey
        </div>
        <div class="event__date event__date--underlined">
          May 22nd and 23rd
        </div>
        <div class="event__location event__location--right">
          Cancún, México
        </div>
      </div>
    </li>
    <li class="event event--is-first">
      <div class="event__meta">
        <div class="event__title">
          Ran out of names
        </div>
        <div class="event__date">
          August 13, 2016
        </div>
        <div class="event__location">
          Hermosillo, México
        </div>
      </div>
    </li>
  </ul>

</div>


更多信息:

Battling BEM (Extended Edition): 10 Common Problems And How To Avoid Them

More Transparent UI Code with Namespaces

事件

Xcaret