БЭМ — методология, разработанная Яндексом для ускорения разработки, читаемости и повторного использования HTML/CSS кода.
В её основе лежит принцип разделения интерфейса на сущности:
Блок, Элемент, Модификатор.
Подробнее на https://ru.bem.info/methodology/quick-start/
Пример разметки по БЭМ:
<ul class="main-menu">
<li class="main-menu__item">
<a class="main-menu__link main-menu__link--active" href="#1">Пункт 1</a>
</li>
<li class="main-menu__item">
<a class="main-menu__link" href="#2">Пункт 2</a>
</li>
<li class="main-menu__item">
<a class="main-menu__link" href="#3">Пункт 3</a>
</li>
</ul>
- Разрешено использовать только классы, нельзя именовать блоки через id.
- Классы пишутся в нижнем регистре. Если класс состоит из нескольких слов, то их нужно разделять дефисом «
-
», например «main-menu
». - В CSS нельзя стилизовать элементы каскадом, например:
.main-menu__item .link
, а также использовать названия элементов.main-menu__item a
.
Независимый компонент страницы, который может быть повторно использован.
- Блок полностью независим, при перемещении в другое место на странице не теряет своей самодостаточности.
- Блок не должен влиять на свое окружение – нет внешних отступов (margin) и позиционирования.
- Блоки можно вкладывать друг в друга.
Наименование блоков
Имена блоков должны отображать смысл «что это?» — логотип, меню, форма. А не внешний вид «какой, как выглядит?» — серый, большой и т.д:
имя-блока
Часть блока, которая не может использоваться в отрыве от него.
Наименование элементов
Название элемента характеризует смысл «что это?» — пункт меню, ссылка. А не состояние «какой, как выглядит?» — красный, большой.
Имя элемента должно начинаться с названия блока, название элемента пишется через разделитель «__
»:
имя-блока__имя-элемента
<!-- Блок «main-menu» -->
<ul class="main-menu">
<!-- Элемент «main-menu__item» -->
<li class="main-menu__item">
<!-- Элемент «main-menu__link» -->
<a class="main-menu__link" href="#1">Пункт 1</a>
</li>
...
</ul>
Элементы можно вкладывать друг в друга, но в названии нельзя прописывать иерархию, например: «main-menu__item_link
».
Сущность, определяющая внешний вид, состояние или поведение блока, или элемента.
Наименование модификаторов
Название модификатора характеризует внешний вид или состояние «какой цвет?», «какой размер?» — красный, выделенный и т.д.
Имя модификатора отделяется от имени блока или элемента одним подчеркиванием «_
»:
имя-блока_имя-модификатора
имя-блока__имя-элемента_имя-модификатора
Или более читаемый вариант «--
»:
имя-блока--имя_модификатора
имя-блока__имя-элемента--имя-модификатора
Также в модификаторе можно передать значение:
имя-блока--имя-модификатора_значение-модификатора
имя-блока__имя-элемента--имя-модификатора_значение-модификатора
<!-- Блок «main-menu» -->
<ul class="main-menu">
<!-- Элемент «main-menu__item» -->
<li class="main-menu__item">
<!-- Элемент «main-menu__link» с модификатором «main-menu__link--active» -->
<a class="main-menu__link main-menu__link--active" href="#1">Пункт 1</a>
</li>
...
</ul>
Модификатор нельзя использовать в отрыве от модифицируемого блока или элемента.
Прием, позволяющий использовать разные БЭМ-сущности на одном DOM-узле без дублирования кода.
Иногда в названиях классов используют префексы, можно обойтись без них, для самого БЭМ они не нужны.
b-
(блок) помогают реализовать пространства имён.l-
(layout) используется для выделения лайаутных блоков, которые используются для позиционирования, ширины и т.д.g-
(global) префикс для глобальных классов.js-
только для навешивания JS-обработчиков (для таких классов нельзя писать стили).
Придерживаться рекомендуемой файловой структуры не обязательно.
При использовании на проекте сборщиков (например Webpack) каждый БЭМ-блок хранится в своей отдельной директории/файле, т.е. один блок — одна директория. В неё помещаются изображения и скрипты данного блока.
src/ # Исходники
blocks/ # БЭМ-блоки
main-menu/ # БЭМ-блок
img/ # Изображения БЭМ-блока
main-menu.less # Стили БЭМ-блока
main-menu.js # Скрипты БЭМ-блока
...
Такая файловая структура позволяет легко поддерживать и повторно использовать код.