BEM

БЭМ (Блок, Элемент, Модификатор) — компонентный подход к веб-разработке. В его основе лежит принцип разделения интерфейса на независимые блоки. Он позволяет легко и быстро разрабатывать интерфейсы любой сложности и повторно использовать существующий код, избегая «Copy-Paste».

Дополнительные ссылки

Возможности БЭМ

  • Простая поддержка структуры кода при росте проекта.
  • Повторное использование кода.
  • Точечные изменения с минимальными затратами: обновление дизайна, добавление функциональных элементов и т. д.

Правила формирования имен

block-name__elem-name_mod-name

  • Имена записываются латиницей в нижнем регистре.
  • Для разделения слов в именах используется дефис (-).
  • Имя блока задает пространство имен для его элементов и модификаторов.
  • Имя элемента отделяется от имени блока двумя подчеркиваниями (__).
  • Имя модификатора отделяется от имени блока или элемента одним подчеркиванием (_).
  • Значение булевых модификаторов в имени не указывается.

Блок

Функционально независимый компонент страницы, который может быть повторно использован. В HTML блоки представлены атрибутом class.


Особенности:
  • Название блока характеризует смысл («что это?» — «меню»: menu, «кнопка»: button), а не состояние («какой, как выглядит?» — «красный»: red, «большой»: big).

    Пример

    <!-- Верно. Семантически осмысленный блок `error` -->
    <div class="error"></div>
    
    <!-- Неверно. Описывается внешний вид -->
    <div class="red-text"></div>
  • Блок не должен влиять на свое окружение, т. е. блоку не следует задавать внешнюю геометрию (в виде отступов, границ, влияющих на размеры) и позиционирование.
  • В CSS по БЭМ также не рекомендуется использовать селекторы по тегам или id.

Таким образом обеспечивается независимость, при которой возможно повторное использование или перенос блоков с места на место.


Вложенность
  • Блоки можно вкладывать друг в друга.
  • Допустима любая вложенность блоков.

Например, блокheadможет содержать логотип(logo), форму поиска(search)и блок авторизации(auth).

Пример

<!-- Блок "header" -->
<div class="header">
  <!-- Вложенный блок "logo" -->
  <div class="logo"><a href="#">логотип</a></div>

  <!-- Вложенный блок "search" -->
  <div class="search"></div>
</div>

Повторное использование

В интерфейсе может одновременно присутствовать несколько экземпляров одного и того же блока.

Элемент

Составная часть блока, которая не может использоваться в отрыве от него.

Элементы не существуют вне блока. Каждый элемент может принадлежать только одному блоку.

Например, пункт меню вне блока меню не используется, значит является его элементом.

Пример 1:

<!-- Блок "вебформа" -->
<div class="wf">
  <!-- Элемент "field" блока "wf" -->
  <div class="wf__field">
    <!-- Элемент "input" блока "wf" -->
    <input class="wf__input" type="text">
  </div>
</div>

Пример 2:

<!-- Блок `search-form` -->
<form class="search-form">
    <!-- Элемент `input` блока `search-form` -->
    <input class="search-form__input">

    <!-- Элемент `button` блока `search-form` -->
    <button class="search-form__button">Найти</button>
</form>

Особенности:
  • Название элемента характеризует смысл («что это?» — «пункт»: item, «текст»: text), а не состояние («какой, как выглядит?» — «красный»: red, «большой»: big).
  • Структура полного имени элемента соответствует схеме:имя-блока__имя-элемента. Имя элемента отделяется от имени блока двумя подчеркиваниями (__).

Вложенность
  • Элементы можно вкладывать друг в друга.
  • Допустима любая вложенность элементов.
  • Элемент — всегда часть блока, а не другого элемента. Это означает, что в названии элементов нельзя прописывать иерархию вида block__elem1__elem2.

Принадлежность

Элемент — всегда часть блока и не должен использоваться отдельно от него.


Необязательность

Элемент — необязательный компонент блока. Не у всех блоков должны быть элементы.

Когда создавать блок, когда — элемент?

Создавайте блок

Если фрагмент кода может использоваться повторно и не зависит от реализации других компонентов страницы.


Создавайте элемент

Если фрагмент кода не может использоваться самостоятельно, без родительской сущности (блока).

Исключение составляют элементы, реализация которых для упрощения разработки требует разделения на более мелкие части — подэлементы. В БЭМ-методологии нельзя создавать элементы элементов. В подобном случае вместо элемента необходимо создавать служебный блок.

Модификатор

Cущность, определяющая внешний вид, состояние или поведение блока либо элемента.


Особенности:
  • Название модификатора характеризует внешний вид («какой размер?», «какая тема?» и т.п. — «размер»: size_s, «тема»: theme_islands), состояние («чем отличается от прочих?» — «отключен»: disabled, «фокусированный»: focused) и поведение («как ведет себя?», «как взаимодействует с пользователем?» — «направление»: directions_left-top).
  • Имя модификатора отделяется от имени блока или элемента одним подчеркиванием (_).

С точки зрения БЭМ-методологии модификатор не может использоваться в отрыве от модифицируемого блока или элемента. Модификатор должен изменять вид, поведение или состояние сущности, а не заменять ее.

Микс

Прием, позволяющий использовать разные БЭМ-сущности на одном DOM-узле.

Миксы позволяют:

  • совмещать поведение и стили нескольких сущностей без дублирования кода;
  • создавать семантически новые компоненты интерфейса на основе имеющихся.

Пример

<!-- Блок `header` -->
<div class="header">
    <!-- К блоку `search-form` примиксован элемент `search-form` блока `header`-->
    <div class="search-form header__search-form"></div>
</div>

В данном примере мы совместили поведение и стили блокаsearch-formи элементаsearch-formблокаheader. Такой подход позволяет нам задать внешнюю геометрию и позиционирование в элементеheader__search-form, а сам блокsearch-formоставить универсальным. Таким образом, блок можно использовать в любом другом окружении, потому что он не специфицирует никакие отступы. Это позволяет нам говорить о его независимости.