Надлежащее использование БЭМ в CSS

Я опытный пользователь CSS, но недавно решил рискнуть и начать использовать БЭМ. По большей части я понимаю ценность использования такой плоской системы, избегая слишком конкретных селекторов и т. д.

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

.badge {
  /* additional declarations */
  background: rgba(0, 0, 0, 0.2);
}
.badge--error {
  background: red;
}
.badge--success {
  background: green;
}

Это прекрасно работает из-за каскадной природы CSS. Таким образом, фон по умолчанию успешно перезаписывается модификатором. Но если я поставлю модификатор перед начальным объявлением, модификатор будет проигнорирован (из-за равной специфичности).

Есть ли проблемы с написанием БЭМ таким образом? Считается ли плохой практикой объявлять значение по умолчанию что-то вроде background внутри блока, если оно должно быть перезаписано модификаторами? Должен ли background по умолчанию в данном случае жить в модификаторе .badge--default? Или я написал это в истинном стиле БЭМ, а БЭМ фактически полагается на каскадирование CSS, чтобы оставаться плоским?


person DanMad    schedule 02.09.2018    source источник
comment
Точно, вы не должны использовать расширения, модификаторы, перед основным Блоком. Нет ничего хрупкого. так работает специфичность CSS. Глобальные значения располагаются поверх вашего CSS, а переопределения — внизу. В современном мире, если вы используете препроцессор CSS, это помогает вам лучше структурировать вашу модель. См. часть SCSS в stackoverflow.com/a/20811902/383904.   -  person Roko C. Buljan    schedule 02.09.2018
comment
Спасибо @RokoC.Buljan, этот комментарий (и предоставленная ссылка) отвечает на мой вопрос.   -  person DanMad    schedule 02.09.2018
comment
Пожалуйста   -  person Roko C. Buljan    schedule 02.09.2018


Ответы (1)


Вы можете использовать переменные CSS

.badge {
  background: var(--background);
}

.badge--error {
  --background: var(--error);
}

.badge--success {
  --background: var(--success);
}


:root {
  --background: yellow;
  --error: red;
  --success: green;
}
<div class="badge">
  a badge
</div>

<div class="badge badge--success">
  a badge success
</div>

<div class="badge badge--error">
  a badge error
</div>

<div class="badge" style="--background: purple">
  a badge random
</div>

Я не понимаю, почему модификатор не может изменить только фон, если он (не) установлен в исходном элементе.

Для BEM я могу порекомендовать использовать препроцессор CSS, например SASS, так как он упрощает вложение элементов, меньше изменений в объявлении какого-либо модификатора перед первоначальным объявлением. Благодаря вложенности ваш CSS становится намного более организованным. Также проще импортировать различные компоненты, чтобы каждый компонент мог жить в своем собственном файле.

С помощью SASS вы можете:

.badge {
  &--error {}
  &--success {}
}
person SuperDJ    schedule 02.09.2018
comment
Спасибо за это. Я намеренно удалил все ссылки из Sass/SCSS, поскольку пытался сосредоточиться на БЭМ и выяснить, должны ли свойства, которые должны были быть перезаписаны модификатором, жить внутри/или отдельно от исходного блока. Тем не менее, я определенно буду использовать Sass, чтобы сэкономить время ;) - person DanMad; 02.09.2018