BEM
Блок — это самостоятельная часть страницы
- Название класса должно быть простым и коротким.
- Название класса должно отвечать на вопрос «Что это?»
- Не используйте сокращения кроме наиболее частыхopen in new window
- Название не должно отвечать на вопрос «Как выглядит?»
<!-- .product — БЭМ-блок -->
<div class="product">...</div>
2
Элемент — часть БЭМ-блока
- Название класса формируется из названия блока с добавлением
__
и названия элемента. - Название класса должно быть простым и коротким.
- Название класса должно отвечать на вопрос «Что это?»
<div class="product">
<!-- product__image — БЭМ-элемент блока product -->
<img class="product__image" src="..." alt="..." />
<!-- product__description — БЭМ-элемент блока product -->
<p class="product__description">...</p>
<!-- product__more-link — БЭМ-элемент блока product -->
<a class="product__more-link" href="">...</a>
</div>
2
3
4
5
6
7
8
9
10
Элемент можно использовать вне его блока только в исключительных случаях
Элемент — часть блока, но, поскольку, БЭМ-дерево независимо от HTML-дерева, элемент можно использовать и вне его блока в некоторых исключительных условиях (сам блок должен быть на странице).
<div class="block">…</div>
...
<div class="block__element">…</div>
2
3
Пример: расположение попапа-элемента не внутри блока-родителя, а в самом конце DOM (дабы показывать попап независимо от ограничения видимости родителей).
Если Вы используете БЭМ только как метод именования селекторов, при написании разметки никогда не используйте элемент вне блока.
Как отличить БЭМ-блок и БЭМ-элемент
Просто задайте себе вопрос: «Эта сущность может потребоваться мне отдельно, сама по себе? Или она нужна только внутри её родителя?» Если нужна отдельно — это БЭМ-блок, если мыслима только внутри родителя — это БЭМ-элемент.
В действительно сомнительных случаях делайте выбор в пользу БЭМ-блока.
Не забывайте о миксовании (возможности иметь на одном теге и класс уровня БЭМ-элемента какого-то родительского блока, и свой класс уровня БЭМ-блока).
На всех проектах (кроме совсем уж крошечных или имеющих гарантировано нулевую возможность модификации) есть фрагменты дизайна, которые мудро всегда делать БЭМ-блоками по причине высокой вероятности повторения.
Некоторые фрагменты дизайна — всегда БЭМ-блоки
- Кнопка (любые кнопки)
- Блоки внутри форм (блок для текстового поля, блок для радиокнопки и т.п.)
- Пагинация
- Табы
- Лейблы (метки)
- Социальные ссылки
- «Лайк» со счётчиком
Модификатор — дополнительный класс для смены оформления или поведения
- Название класса формируется из названия блока/элемента с добавлением -- и названия модификатора.
- Название должно быть простым и коротким.
- Название класса может отвечать на вопросы «Что это?», «Что меняется?», «Чем отличается от прочих?»
- Модификатор нельзя использовать самостоятельно
<!-- .product--large — БЭМ-модификатор -->
<div class="product product--large">...</div>
<!-- ОШИБКА: модификатор без класса, который он модифицирует -->
<div class="product--sale">...</div>
2
3
4
5
Миксование — комбинирование на одном теге классов БЭМ-блока и БЭМ-элемента
Комбинация возможна в любом сочетании: БЭМ-блок + БЭМ-элемент, БЭМ-блок + БЭМ-блок, БЭМ-элемент + БЭМ-элемент
<div class="page-header">
<div class="page-header__nav-wrap">...</div>
<a class="btn page-header__btn" href="/buy">...</a>
</div>
<div class="slider">
<div class="promo slider__inner">
<div class="promo__item slider__item">...</div>
</div>
</div>
2
3
4
5
6
7
8
9
Один БЭМ-блок = один файл
В файловой системе при работе с CSS-препроцессорами каждый БЭМ-блок должен быть описан в своём отдельном файле.
// файл slider.scss
.slider {
//...
}
// файл promo.scss
.promo {
//...
}
2
3
4
5
6
7
8
9
БЭМ-дерево плоское, в отличие от DOM
В классах БЭМ-элементов нельзя прописывать иерархию (два и более сегмента __
недопустимы).
<div class="promo">
<div class="promo__description">
<!-- Нет ошибки: вложенный элемент не имеет особенностей -->
<a class="promo__link" href="">...</a>
</div>
</div>
<div class="promo">
<div class="promo__description">
<!--ОШИБКА: попытка прописать иерархию -->
<a class="promo__description__link" href="">...</a>
</div>
</div>
2
3
4
5
6
7
8
9
10
11
12
13
Файловая организация
- Один БЭМ-блок = один препроцессорный файл. Всегда.
- Файл со стилизацией БЭМ-блока должен называться так же, как сам блок.
# Один из вариантов файловой организации (удобно должно быть ВАМ)
src/ # папка с исходниками, из которых собирается проект
blocks/ # папка с БЭМ-блоками
page-header/ # папка БЭМ-блока
img/ # картинки, используемые в БЭМ-блоке
page-header.scss # стилизация БЭМ-блока
page-header.html # разметка БЭМ-блока (не обязательно)
page-header.js # доп. интерактив БЭМ-блока (не обязательно)
page-footer/ # папка БЭМ-блока
logo/ # папка БЭМ-блока
...
less/
mixins/ # папка с примесями
style.scss # диспетчер подключений (только импорты)
variables.scss # переменные проекта
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@import
- Компилируйте один файл (диспетчер подключений), в котором подключаются все прочие.
- Импортируйте файлы только в диспетчере подключений (допустимо импортировать примеси внутри отдельного файла, например,
mixins.scss
). - Не пишите никаких селекторов в диспетчере подключений.
- Не импортируйте файлы внутри медиа-условий.
- Один БЭМ-блок = один препроцессорный файл.
// style.scss
@import "variables.scss"; // правильно
@import "mixins.scss"; // правильно
@import "../blocks/page-header/page-header.scss"; // правильно
@import "../blocks/page-footer/page-footer.scss"; // правильно
@import "responsive-imports.scss"; // неправильно, если внутри этого файла есть импорты
@import "top-part-page.scss"; // неправильно, если нет такого БЭМ-блока
// неправильно, импорт внутри @media
@media screen and (min-width: $laptop-min) {
@import "../blocks/promo/promo.scss";
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Вложения селекторов
- Чем меньше уровней вложенности, тем лучше.
- Не допускайте более 3-х уровней вложенности (псевдоэлемены, псевдоселекторы и медиа-условия не считаются увеличивающими вложенность).
- Осторожно используйте жесткое наследование.
- Всегда оставляйте пустую строку перед вложенным селектором или
@media
. - Всегда делайте дополнительный отступ для вложений.
.promo {
display: block;
// пустая строка для улучшения читаемости
a { // первый уровень вложенности
color: #ff0000;
// пустая строка для улучшения читаемости
&:hover { // не увеличивает уровень вложенности
...
}
}
}
2
3
4
5
6
7
8
9
10
11
@media
- Вкладывайте
@media
в селекторы, а не наоборот. - Не вкладывайте
@media
друг в друга. - Пишите
@media
рядом, не пишите селекторы между ними. - Пишите условия для
@media
там, где используете@media
, не пишите условия в переменных.
.promo {
display: block;
// Хорошо: условие очевидно, в переменной только ширина
@media (min-width: $screen-md) {
display: none;
}
@media (min-width: $screen-lg) {
display: block;
}
// Плохо: условие целиком вынесено в переменную (неочевидность)
@media ($mobile-width) {
display: block;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Амперсанд
- Используйте амперсанд только перед:
- разделителем БЭМ-элемента,
- разделителем БЭМ-модификатора,
- псевдоэлементом или псевдоселектором.
- Никогда не используйте амперсанд в местах разделения словосочетаний имён блоков, элементов или модификаторов (см. пример).
- Никогда не повторяйте написанный с амперсандом селектор внутри одного контекста.
.promo {
// Правильно: амперсанд перед псевдоклассом
&:hover { ... }
// Правильно: амперсанд перед разделителем элемента
&__item {
// НЕПРАВИЛЬНО: амперсанд в месте разделения словосочетания в названии элемента
&-link { ... }
}
// НЕПРАВИЛЬНО: амперсанд в месте разделения словосочетания в названии блока
&-shover { ... }
// Правильно: модификаторы нужно писать под элементами
&--large { ... }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Переменные
- Выносите в переменные (как минимум):
- цвета,
- размеры шрифтов и интерлиньяж (все значения интерлиньяжа можно не выносить в переменные, а задавать его в отн. единицах),
- брейкпоинты
- Для средних и крупных проектов определяйте в переменных цвета ссылок, бордюры, тени и прочие часто использующиеся величины.
- Если при стилизации конкретных блоков указываете размер шрифта через переменную, указывайте интерлиньяж тоже через переменную, или через мат. операцию (от базового интерлиньяжа или от размера шрифта), или в относительных единицах (em).
- Отделяйте смысловые блоки с переменными пустыми строками.
- Используйте БЭМ-именование для переменных.
$color-main: #0275d8;
$color-success: #5cb85c;
$color-danger: #d9534f;
$text-color: $gray-darkest;
$text-color--muted: $gray;
$font-size: 1.6rem;
$font-size--h1: 3rem;
...
$font-size--small: 0.75em;
$line-height: 1.375em;
$font-family: 'Roboto', Arial, sans-serif;
$screen-xs: 0;
$screen-sm: 480px;
$screen-md: 768px;
$screen-lg: 992px;
$screen-xl: 1200px;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21