Как выразить структурные псевдоклассы (ex `: last-child`) в BEM? - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь выразить простой селектор 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>

Как я могу выразить последний селектор в терминах БЭМ?

Единственный способ, которым я могу придумать, - это добавить модификатор

.block__subelem--not-last-child {

}

, а затем добавить логику в HTMLсзади, но для меня это просто неправильно, это добавляет сложности на стороне сервера и подвержено ошибкам.

1 Ответ

0 голосов
/ 20 декабря 2018

Одной из целей БЭМ является предсказуемость .

Теория

Например, в следующем коде, выполненном без БЭМ, нельзя ожидать разных стилей между двумя элементами с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>

С помощью БЭМ мы явно указываем блок, чтобы уменьшить вес селектора и , чтобы обеспечить предсказуемость.Итак, читая 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>
...