БЭМ (Блок, Элемент, Модификатор) — компонентный подход к веб-разработке. В его основе лежит принцип разделения интерфейса на независимые блоки. Он позволяет легко и быстро разрабатывать интерфейсы любой сложности и повторно использовать существующий код, избегая.
Блок - часть страницы, являющаяся логически независимой от остального наполнения. Представляет собой «строительную единицу» для сайта (на примере конструктора лего - это отдельный «кирпичик»). Блок не отвечает за свое расположение. Он задает внутренние свойства (размеры, шрифты и т.д.).
Элемент - часть блока, которая должна входить в состав блока и не иметь какого-либо смысла отдельно от блока.
Модификатор - третья составляющая БЭМ может задавать как дополнительное поведение для блока/ элемента, так и переопределять стандартное.
Блоки, элементы и модификаторы называются БЭМ-сущностями.
Представление структуры веб-страницы в терминах блоков, элементов и модификаторов называется БЭМ-деревом. Это абстракция над DOM-деревом, которая описывает имена БЭМ-сущностей, их состояния, порядок, вложенность и вспомогательные данные. БЭМ-дерево не привязано к визуальному представлению блоков, оно отображает только логику.
Основная идея соглашения по именованию - сделать имена CSS-селекторов максимально информативными и понятными, чтобы упростить разработку и отладку кода.
Полное имя элемента/модификатора формируется так, чтобы из него можно было определить принадлежность данного элемента/
модификатора к конкретному блоку.
По имени модификатора элемента должно быть возможно определить принадлежность данного модификатора к конкретному
элементу конкретного блока.
Правила формирования имени БЭМ-сущности:
- Каждая БЭМ-сущность должна иметь свой класс.
- CSS-свойства для блоков, элементов и модификаторов описываются только через классы.
- Для разделения слов в именах используется дефис (-).
- Элемент отделяется от блока двумя подчеркиваниями (__). Модификатор - одним (_).
- Имена БЭМ-сущностей записываются с помощью цифр и латинских букв в нижнем регистре.
Пример:
Имя блока - header
.
Имя элемента блока - header__search-form
- элемент search-form блока header.
Имя модификатора блока - header_theme_green-forest
- модификатор theme в значении green-forest блока header.
Имя модификатора элемента - header__search-form_disabled
- булев модификатор disabled элемента search-form блока header.
<header class='header header_theme_green-forest'>...</header>
Логически и функционально независимый компонент страницы. Блок полностью самодостаточен: у него может быть свое поведение, шаблоны, стили, документация и не только. Одни блоки можно вкладывать в другие, компоновать, использовать для создания более сложных блоков.
- Блок можно перемещать в пределах одной страницы, разных страниц или проектов.
- В интрефейсе одновременно может использоваться любое количество экземпляров блоков.
- Название блока характеризует смысл ("Что это?" - "Кнопка":
button
), а не состояние. - Блок не должен влиять на свое окружение, т. е. блоку не следует задавать внешнюю геометрию (в виде отступов, границ, влияющих на размеры) и позиционирование. Позиционирование осуществляется с помощью вспомогательных элементов (
header__menu
). - Блок не должен зависеть от окружающих его блоков и сам не должен влиять на соседние блоки, поэтому нельзя использовать тэги, вложенные селекторы и глобальные сбросы стилей для страницы (для этого необходимо создавать независимый блок).
Часть блока, которая не может использоваться в отрыве от него и имеет смысл только в рамках своего родителя. Например, пункт меню вне контекста блока меню не используется, значит является элементом. Элементы могут быть обязательными и опциональными.
- Название блока характеризует смысл (и отвечает на вопрос "Что это?" - "Текст":
__text
), а не состояние. - Допустима любая вложенность элементов друг в друга.
- Элемент является не обязательным компонентов блока.
- Элемент всегда часть блока и не должен использовать самостоятельно.
- Нельзя создавать элементы элементов, из-за чего возможность изменять внутренную структуру блока ограничивается
Свойство блока или элемента, которое меняет их внешний вид, состояние или поведение.
Модификатор имеет имя и может иметь значение. Использование модификаторов опционально. У блока/элемента может быть
несколько разных модификаторов одновременно.
- Название модификатора характеризует:
- внешний вид ("какой размер?", "какая тема?" и т. п. - "размер":
_size_s
, "тема":_theme_islands
), - состояние ("чем отличается от прочих?" "отключен":
_disabled
, "фокусированный":_focused
), - поведение ("как ведет себя?", "как взаимодействует с пользователем?" - "направление":
_directions_left-top
).
- внешний вид ("какой размер?", "какая тема?" и т. п. - "размер":
- Имя модификатора не должно отражать значение свойства сущности ("какой размер?" - "10px":
_size_10px
). - Булевый модификатор используют, когда важно только наличие или отсутствие модификатора, а его значение несущественно. Например, "отключен":
_disabled
. Считается, что при наличии булевого модификатора у сущности его значение равно true. - Модификатор "ключ-значение" используют, когда важно значение модификатора. Например, "меню с темой оформления":
_menu_theme_islands
. - Модификатор не может использоваться в отрыве от модифицируемого блока или элемента.
Блоки могут быть реализованы в одной или нескольких технологиях:
- поведение — JavaScript, CoffeeScript;
- внешний вид — CSS, Stylus, Sass;
- шаблоны — Pug, Handlebars, XSL, BEMHTML, BH;
- документация — Markdown, Wiki, XML.
Например, если внешний вид блока задан с помощью CSS, это означает, что блок реализован в технологии CSS. А если документация к блоку написана в формате Markdown — блок реализован в технологии Markdown.
Принятый в методологии БЭМ компонентный подход применяется и к организации проектов в файловой структуре. Реализации блоков, элементов и модификаторов делятся на независимые файлы-технологии, что позволяет нам подключать их опционально.
- Один блок — одна директория.
- Имена блока и его директории совпадают. Например, блок
header
— директорияheader/
. - Реализация блока разделяется на отдельные файлы-технологии. Например,
header.css
,header.js
. - Директория блока является корневой для поддиректорий соответствующих ему элементов и модификаторов.
- Имена директорий элементов начинаются с двойного подчеркивания (__). Например,
header/__logo/
,menu/__item/
. - Имена директорий модификаторов начинаются с одинарного подчеркивания (_). Например,
header/_fixed/
,menu/_theme_islands/
. - Реализации элементов и модификаторов разделяются на отдельные файлы-технологии. Например,
header__input.js
,header_theme_islands.css
. - В своей практике я выделяю реализацию в отдельный файл только для блоков, при этом элементы и модификаторы описываю в представлении блоков
супер!)