БЭМ и Sass
Имена по БЭМ длинные, и в CSS приходится много раз повторять имя блока. Многие проекты пишут стили в Sass — это препроцессор: программа, которая превращает код на расширенном языке в обычный CSS. Файлы Sass имеют расширение .scss, а в браузер попадает уже готовый .css.
Склейка имён через &
В Sass символ & внутри правила означает селектор родителя, и к нему можно приклеить продолжение имени. Так блок, его элементы и модификаторы пишутся одной группой:
.card {
padding: 12px;
border: 1px solid silver;
&__title {
margin: 0 0 4px;
}
&__price {
color: seagreen;
}
&--sale {
border-color: crimson;
}
}После обработки получаются обычные селекторы из одного класса:
.card { padding: 12px; border: 1px solid silver; }
.card__title { margin: 0 0 4px; }
.card__price { color: seagreen; }
.card--sale { border-color: crimson; }Специфичность осталась плоской — Sass лишь сократил запись.
Во встроенной вложенности так нельзя
В уроке «Вложенность CSS» вы видели, что & есть и в обычном CSS. Но там это ссылка на селектор целиком, а не кусок текста: склеить &__title в .card__title браузер не умеет:
<style>
.card {
padding: 12px;
border: 1px solid silver;
&__title { color: crimson; }
}
</style>
<div class="card">
<h3 class="card__title">Заголовок остался чёрным</h3>
</div>Рамка у карточки есть, а правило &__title не сработало. Поэтому склейку имён используют только в Sass и похожих препроцессорах.
Модификатор, который меняет элементы
Исключение из прошлого урока — модификатор блока, влияющий на элемент, — в Sass тоже записывается коротко:
.card {
&__price {
color: seagreen;
}
&--sale &__price {
color: crimson;
}
}Получится .card--sale .card__price — ровно тот селектор из двух классов, который мы писали руками.
Порядок внутри файла блока
Удобно держать единый порядок: сначала стили самого блока, затем его модификаторы, затем элементы с их модификаторами. Тогда в любом файле блока нужное правило ищется за секунды, а модификаторы стоят ниже основных стилей и побеждают их.
Частая ошибка
Вкладывать элементы так, как они вложены в разметке:
.card {
.card__body {
.card__title {
color: rebeccapurple;
}
}
}Без & получается селектор потомка .card .card__body .card__title — три класса вместо одного. Такое правило трудно перебить модификатором, и вся польза БЭМ пропадает. Пишите &__title на первом уровне внутри блока.