БЭМ: Что могут изменять модификаторы?

Допустим, у меня есть следующий CSS для универсального компонента списка, использующий BEM и SCSS:

.list {
  &__item {
    &:not(:last-child) {
      margin-right: .3em;
    }
  }
}

Я хочу добавить модификатор, который может сделать список вертикальным, например:

.list--vertical {
  display: flex;
  flex-direction: column;
}

Моя проблема возникает, когда я думаю о полях для элементов list__item. Для вертикальных списков я хочу, чтобы мое поле было внизу, а не справа от каждого элемента. Если я правильно понял БЭМ, я не могу изменить стиль list__item на основе модификатора list, это правильно?

Чтобы быть более точным, это то, что я хочу сделать:

.list--vertical {
  display: flex;
  flex-direction: column;

  .list__item {
    &:not(:last-child) {
      margin-bottom: .3em;
      margin-right: 0;
    }
  }
}

Каков принятый способ справиться с этим с помощью БЭМ? Другой модификатор для list__item, который обрабатывает поля? Другой блок полностью для вертикальных списков?


person Malax    schedule 25.10.2016    source источник


Ответы (1)


Каков принятый способ справиться с этим с помощью БЭМ?

Зависит от того, какую версию БЭМ вы используете. Я использую вариант концепции BEM до спецификации., что означает, что если вы будете подписываться на bem.info, у вас будут разные ответы.


Модификаторы должны быть прикреплены к элементу, который они модифицируют. Однако изменение блока позволяет модификатору наследоваться дочерними элементами:

<div class="foo foo--example">
  <div class="foo__bar foo--example__bar">...</div>
<div>

Это становится беспорядочным, когда дочерние элементы также имеют модификаторы:

<div class="foo foo--example">
  <div class="
    foo__bar
    foo--example__bar
    foo__bar--another-example
    foo--example__bar--another-example">...</div>
<div>

Эта форма синтаксиса БЭМ довольно многословна. Его лучше всего использовать в сгенерированном коде.


Я использую LESS для предварительной обработки CSS, поэтому мой БЭМ-код часто выглядит так:

.foo {
  ...

  &__bar {
    ...
  }
}

С модификаторами становится:

.foo {
  ...

  &__bar {
    ...
  }

  &--example {
    ...

    &__bar {
      ...
    }
  }
}

Это гарантирует, что каскад находится в правильном порядке и что все селекторы по-прежнему имеют только один класс.

person zzzzBov    schedule 25.10.2016
comment
Благодарю вас! Просто чтобы быть уверенным: вы считаете последний пример кода, который я опубликовал, действительным? - person Malax; 25.10.2016
comment
@Malax, использование селектора потомков действительно, но я определенно рекомендую избегать их, когда это возможно. Иногда намного быстрее избежать добавления дополнительных классов-модификаторов к каждому отдельному дочернему элементу. Но у меня были ситуации, что это возвращалось, чтобы укусить меня позже. Поскольку LESS и Sass значительно упрощают наследование, подумайте, хотите ли вы иметь блок vertical-list и блок horizontal-list, каждый из которых наследуется от базового блока list. - person zzzzBov; 25.10.2016