如何在BEM中表达结构化伪类(例如:: last-child)?

时间:2018-12-19 14:52:02

标签: css bem

我试图在BEM中表达一个简单的CSS3选择器:

CSS

.block__elem {
  /* ELEM RULES */
}

.block__subelem {
  /* SUBELEM RULES */
}

.block__elem:not(:last-child) .block__subelem {
  /* HOW CAN I EXPRESS THIS? */
}

HTML

<div class="block__elem">
  <div class="block__subelem">CONTENT</div>
  <div class="block__subelem2">OTHER CONTENT</div>
</div>
<div class="block__elem">
  <div class="block__subelem">CONTENT</div>
  <div class="block__subelem2">OTHER CONTENT</div>
</div>
<div class="block__elem">
  <div class="block__subelem">THIS SHOULD HAVE A SLIGHTLY DIFFERENT STYLE</div>
  <div class="block__subelem2">OTHER CONTENT</div>
</div>

如何用BEM术语表示最后一个选择器?

我唯一想到的方法是添加修饰符

.block__subelem--not-last-child {

}

然后将逻辑从后面添加到HTML中,但是对我来说,这是错误的,它增加了服务器端的复杂性,并且容易出错。

1 个答案:

答案 0 :(得分:-1)

BEM的目的之一是可预测性

理论

例如,在下面的没有BEM的代码中,您不能期望两个带有title类的元素之间的样式不同。

<div class="article">
  <div class="title"></div>
  <ul class="comments">
    <li class="comment">
      <div class="title"></div>
    </li>
  </ul>
</div>
<style>
  .article > .title { }
  .comment > .title { }
</style>

使用BEM,我们显式地显示了该块以减小选择器权重,并给出了可预测性。因此,通过阅读HTML,我们知道.article__title.comment_title是两个独立的类。

<div class="article">
  <div class="article__title"></div>
  <ul class="article__comments">
    <li class="comment">
      <div class="comment__title"></div>
    </li>
  </ul>
</div>
<style>
  .article__title { }
  .comment__title { }
</style>

总结:

  

具有相同类和相同块内层次结构的两个元素应具有相同的样式。

实际案例

在您的示例中,您应该明确最后.block__elem的样式差异。

自然的解决方案是使用修饰符,例如.block__elem--last

<div class="block">
  <div class="block__elem">
    <div class="block__subelem">CONTENT</div>
    <div class="block__subelem2">OTHER CONTENT</div>
  </div>
  <div class="block__elem block__elem--last">
    <div class="block__subelem">THIS SHOULD HAVE A SLIGHTLY DIFFERENT STYLE</div>
    <div class="block__subelem2">OTHER CONTENT</div>
  </div>
</div>

但是,在我看来,通常最好使用其他元素,例如.block__last-elem

<div class="block">
  <div class="block__elem">
    <div class="block__subelem">CONTENT</div>
    <div class="block__subelem2">OTHER CONTENT</div>
  </div>
  <div class="block__last-elem">
    <div class="block__subelem">THIS SHOULD HAVE A SLIGHTLY DIFFERENT STYLE</div>
    <div class="block__subelem2">OTHER CONTENT</div>
  </div>
</div>
<style>
  /* Common styles */
  .block__elem .block__sub-elem,
  .block__last-elem .block__sub-elem { }

  /* :not(:last-child) styles */
  .block__elem .block__sub-elem { }
</style>