БЭМ (Блок-Элемент-Модификатор) — методология web-разработки, а также набор интерфейсных библиотек, фреймворков и вспомогательных инструментов.
Основные понятия
«Блок», «элемент» и «модификатор» — основные термины БЭМ. Это необходимые и достаточные понятия для описания интерфейса любой сложности.
Блок
Блок — это независимый интерфейсный компонент. Блок может быть простым или составным (содержать другие блоки). При создании блока нужно обеспечивать возможность его использования в любом месте web-страницы, а также повторения на той же самой странице. Блок должен включать в себя всю реализацию, необходимую для представления части интерфейса, которую он выражает.
Элемент
Элемент — это составная часть блока. Элементы контекстно-зависимы: они имеют смысл только в рамках своего блока. Элемент — не обязательная составляющая блока, небольшие блоки обходятся без элементов.
Модификатор
Модификатор — это свойство блока или элемента, задающее изменения в их внешнем виде или поведении. Модификатор может быть булевым (например, button_big) или парой ключ-значение (например, menu_type_bullet, menu_type_numbers). У блока или элемента может быть несколько модификаторов одновременно.
Цель создания БЭМ
БЭМ предлагает общую семантическую модель для всех технологий, использующихся во фронтэнд разработке (HTML, CSS, JavaScript, шаблоны и др.)
Используя понятия «блок», «элемент» и «модификатор» можно описать древовидную структуру документа. Такое описание называется BEM tree и является семантическим представлением интерфейса, абстракцией над DOM tree.
HTML/CSS
В HTML/CSS блоки, элементы и модификаторы представлены в виде CSS-классов, названных согласно правилам именования (naming convention). Несколько блоков могут быть расположены на одном и том же DOM-узле, в этом случае DOM-узлу назначается 2 CSS-класса. На одном DOM-узле также могут быть одновременно расположены блок и элемент другого блока.
Правила именования БЭМ-классов от Яндекса
CSS-класс блока соответствует имени блока. Для разделения слов в сложных именах блоков используется дефис.
... div>
... ul>
... span>
... div>
CSS-класс элемента содержит имя блока и имя элемента, разделенные двумя знаками underscore.
... div>
... li>
... input>
... div>
CSS-класс модификатора содержит имя блока и имя модификатора, разделенные одним знаком underscore. В том случае, если модификатор — это пара ключ-значение, они тоже разделяются знаком underscore. Для модификатора элемента в CSS-классе сохраняются и имя блока, и имя элемента. CSS-класс модификатора используется в паре с классом своего блока (или элемента).
...
... li>
... span>
... div>
Правила именования БЭМ-классов от Гарри Робертса
Альтернативные правила именования были предложены Гарри Робертсом. Он советует использовать 2 дефиса для разделения имён блока и модификатора.
... div>
... li>
... span>
... div>
Префиксы
Некоторые правила именования рекомендуют использовать префиксы. Так, все классы блоков могут начинаться с префикса b-.
... div>
... ul>
... span>
... div>
Иногда в качестве префикса используют сокращенное имя проекта. Например, OraanjePool-> op.
... div>
... ul>
... span>
... div>
JavaScript
В БЭМ JavaScript работает с абстрактной структурой блоков-элементов и модификаторов, не обращаясь к лежащим за ним DOM-узлам и их CSS-классам напрямую. Кроме того, для идентификации DOM-узлов не используются дополнительные CSS-классы "специально для JavaScript". Для обеспечения такой возможности используется фреймворк или собственный набор хелперов.
Хелперы для работы с БЭМ-структурой
Так, если каждому блоку с JavaScript-функциональностью соответствует объект, его методы позволяют:
обращаться к вложенным элементам: [color=orange][b]// предположим, что blockObj указывает на объект блока
blockObj.elem('panel'); // возвращает элементы
[/b][/color]
работать с модификаторами
предположим, что blockObj указывает на объект блока
На файловой системе блоки, элементы и модификаторы представлены в виде файлов своих реализаций в различных web-технологиях. Файлы, относящиеся к одному блоку, объединяют в одну директорию.
Плоская структура
Самая простая структура проекта не предполагает вложенности в директории блоков: