1. 17. 4. Основные понятия

Блок

«Функционально независимый компонент страницы, который может быть повторно использован». © сайт bem.info.

Это такая часть страницы, которая может рассматриваться, разрабатываться и использоваться самостоятельно (как элемент дизайн-системы, как отдельная осмысленная единица интерфейса, как бизнес-сущность), которая имеет свой ограниченный код и не содержит никаких сведений о том, что находится за её границами.

Шапка, которая есть на любой странице — наверняка блок. Если слайдер можно теоретически использовать не только на главной под шапкой — он будет блоком. Каталог — блок (Новинки, С этим товаром покупают, Похожие товары, ...). Карточку товара можно вытащить из каталога и использовать в другом месте. Кнопок много в разных местах — это блоки. Чем-то похоже на семантический тег <article>, но гораздо шире трактуется и не коррелирует с HTML напрямую.

То есть когда мы говорим о «компонентах», мы говорим об отдельных независимых блоках. Блок — это и есть компонент.

Элемент

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

Вот например, пункт меню не может использоваться вне меню, хотя ссылка на одну из страниц, вероятно, может. Почему вероятно? Потому что в меню эта ссылка обычно используется как будто это кнопка, с увеличенной зоной клика и подчёркиванием по наведению. Если она примерно так же используется в других местах, пусть и с другим декором — это блок. А если на остальном сайте используются только строчные ссылки внутри текста — это по-прежнему элемент.

Ещё элемент — это сущность, которая определяет какую часть блока занимает HTML-элемент (место расположения, ширину/высоту, расстояние до соседей и так далее). Такой своеобразный солдат раскладки.

Модификатор

Это вариативность блока или элемента. Всегда только внешняя.

Например, у нас на сайте есть множество сущностей, которые означают пользовательское действие «кликни, и что-то произойдёт». Где-то это могут быть ссылки, где-то кнопки. Но у них общая функциональность, скорее всего они будут блоками, к которым мы допишем модификаторы, чтобы различать большие и малые, жёлтые и синие. Но внешняя составляющая для модификаторов — не главное, главное — это его функциональность. Например, кнопка первичного действия и кнопка вторичного действия.

Задача верстальщика — определить, какие элементы интерфейса — независимые блоки, а какие — их элементы. Что будет базовым представлением блока, а что его модификацией.

Микс

Это приём, который позволяет использовать разные БЭМ-сущности применительно к одному HTML-элементу.

Один и тот же HTML-элемент может быть БЭМ-блоком и БЭМ-элементом одновременно. Мы же говорили, что это не связано с разметкой напрямую? Например, навигация по сайту наверняка будет блоком, но сеточные стили вроде выравнивания к ней нужно будет привязывать как к элементу шапки. Это называется миксом.

За счёт миксов можно уменьшить количество HTML-элементов на странице, тем самым повысить её показатели по производительности.

Оптимизация страниц

Старайтесь избегать чрезмерного размера DOM. Одной из причин плохих показателей производительности сайта (Performance) в Lighthouse (инструмент для оценки качества сайтов) может большое количество DOM-узлов. Поэтому лучше не увлекаться созданием дополнительных обёрток в разметке. Подробнее про Lighthouse читайте в статье нашего блога.

Если невозможно использовать микс (например, из-за дизайна не получается применить сеточные и другие стили к одному и тому же HTML-элементу), то создаются отдельные обёртки.

БЭМ-дерево

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

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

page /* это страница, блок */
  page__header page-header /* это микс, элемент страницы - шапка, и отдельный блок шапки */
    page__nav container /* микс, навигация как элемент страницы и сеточный контейнер */
      site-navigation /* навигация - блок */
        site-navigation__item /* элемент навигации */
          site-navigation__link /* ещё элемент навигации */
        site-navigation__item
          site-navigation__link site-navigation__link--active /* элемент с модификатором */

Для построения БЭМ-дерева можно использовать генератор БЭМ-дерева от Йоксель, он подсвечивает грубые ошибки и позволяет увидеть весь результат работы в очень прозрачной форме. Нюансы и детали он не учитывает, например, когда на блоке висит и класс элемента этого же блока (<section class="blog blog__title">). Это придётся проверить самостоятельно.

БЭМ-сущность (блок, элемент или модификатор)

Определяется названием класса. Лучше, если у каждой такой сущности будет своя зона ответственности: одна сущность отвечает за внешний вид, другая — за положение на странице. Разные разработчики предпочитают определять принадлежность к бизнес-сущности или элементу интерфейса. Не страшно, если один элемент страницы будет одновременно и блоком, и элементом, и модификатором.

<a class="user-menu__item menu-link menu-user" href="#">Опознанный енот</a>

Нотация

Соглашение по именованию. Их достаточно много, и очень важно придерживаться именно того соглашения, которое принято для этого проекта.

В некоторых проектах используют префиксы (к примеру, b-). Классическая яндексовская нотация БЭМ: имя-блока__имя-элемента_модификатор, при этом обычно имена — односоставные (site-navigation__link_active), а у многих блоков и элементов не будет модификаторов, но нотация показывает самый развёрнутый из возможных вариантов.

Мы будем использовать в обучающих материалах популярную нотацию, где в названии класса элементы отделяются от блока двойным «подчёркиванием» __, а модификаторы — двойным дефисом --.

Last updated