EN RU
Форум

Методология

Технологии

Инструментарий

Библиотеки

Учебные материалы

Быстрый старт

Введение

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

Содержание

Блок

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

Особенности:

Пример

<!-- Верно. Семантически осмысленный блок `error` -->
<div class="error"></div>

<!-- Неверно. Описывается внешний вид -->
<div class="red-text"></div>

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

Принцип работы с блоками

Вложенность

Пример

<!-- Блок `header` -->
<header class="header">
    <!-- Вложенный блок `logo` -->
    <div class="logo"></div>

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

Элемент

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

Особенности:

Пример

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

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

Принципы работы с элементами

Вложенность

Пример

<!--
    Верно. Структура полного имени элементов соответствует схеме:
    `имя-блока__имя-элемента`
-->
<form class="search-form">
    <div class="search-form__content">
        <input class="search-form__input">
        <button class="search-form__button">Найти</button>
    </div>
</form>

<!--
    Неверно. Структура полного имени элементов не соответствует схеме:
    `имя-блока__имя-элемента`
-->
<form class="search-form">
    <div class="search-form__content">
        <!--
            Рекомендуется:
            `search-form__input` или `search-form__content-input`
        -->
        <input class="search-form__content__input">

        <!--
            Рекомендуется:
            `search-form__button` или `search-form__content-button`
        -->
        <button class="search-form__content__button">Найти</button>
    </div>
</form>

Имя блока задает пространство имен, которое гарантирует зависимость элементов от блока (block__elem).

Блок может иметь вложенную структуру элементов в DOM-дереве:

Пример

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2">
            <div class="block__elem3"></div>
        </div>
    </div>
</div>

Однако эта же структура блока в методологии БЭМ всегда будет представлена плоским списком элементов:

Пример

.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}

Это позволяет изменять DOM-структуру блока без внесения правок в коде каждого отдельного элемента:

Пример

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>

    <div class="block__elem3"></div>
</div>

Структура блока меняется, а правила для элементов и их названия остаются прежними.

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

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

Пример

<!-- Верно. Элементы лежат внутри блока `search-form` -->
<!-- Блок `search-form` -->
<form class="search-form">
    <!-- Элемент `input` блока `search-form` -->
    <input class="search-form__input">

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

<!-- Неверно. Элементы лежат вне контекста блока `search-form` -->
<!-- Блок `search-form` -->
<form class="search-form">
</form>

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

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

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

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

Пример

<!-- Блок `search-form` -->
<div class="search-form">
    <!-- Блок `input` -->
    <input class="input">

    <!-- Блок `button` -->
    <button class="button">Найти</button>
</div>

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

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

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

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

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

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

Модификатор

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

Особенности:

Типы модификаторов

Булевый

Пример

<!-- Блок `search-form` имеет булевый модификатор `focused` -->
<form class="search-form search-form_focused">
    <input class="search-form__input">

    <!-- Элемент `button` имеет булевый модификатор `disabled` -->
    <button class="search-form__button search-form__button_disabled">Найти</button>
</form>

Ключ-значение

Пример

<!-- Блок `search-form` имеет модификатор `theme` со значением `islands` -->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

    <!-- Элемент `button` имеет модификатор `size` со значением `m` -->
    <button class="search-form__button search-form__button_size_m">Найти</button>
</form>

<!--
    Невозможно одновременно использовать два одинаковых модификатора
    с разными значениями
-->
<form class="search-form
             search-form_theme_islands
             search-form_theme_lite">

    <input class="search-form__input">

    <button class="search-form__button
                   search-form__button_size_s
                   search-form__button_size_m">
        Найти
    </button>
</form>

Принципы работы с модификаторами

Модификатор нельзя использовать самостоятельно

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

Пример

<!-- Верно. Блок `search-form` имеет модификатор `theme` со значением `islands`-->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

    <button class="search-form__button">Найти</button>
</form>

<!-- Неверно. Отсутствует модифицируемый класс `search-form` -->
<form class="search-form_theme_islands">
    <input class="search-form__input">

    <button class="search-form__button">Найти</button>
</form>

Зачем в именах модификаторов и элементов указывать имя блока?

Микс

Прием, позволяющий использовать разные БЭМ-сущности на одном 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 оставить универсальным. Таким образом, блок можно использовать в любом другом окружении, потому что он не специфицирует никакие отступы. Это позволяет нам говорить о его независимости.

Файловая структура

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

Особенности:

Пример

search-form/                           # Директория блока search-form

    __input/                           # Поддиректория элемента search-form__input
        search-form__input.css         # Реализация элемента search-form__input
                                       # в технологии CSS
        search-form__input.js          # Реализация элемента search-form__input
                                       # в технологии JavaScript

    __button/                          # Поддиректория элемента search-form__button
        search-form__button.css
        search-form__button.js

    _theme/                            # Поддиректория модификатора
                                       # search-form_theme
        search-form_theme_islands.css  # Реализация блока search-form, имеющего
                                       # модификатор theme со значением islands
                                       # в технологии CSS
        search-form_theme_lite.css     # Реализация блока search-form, имеющего
                                       # модификатор theme со значением lite
                                       # в технологии CSS

    search-form.css                    # Реализация блока search-form
                                       # в технологии CSS
    search-form.js                     # Реализация блока search-form
                                       # в технологии JavaScript

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

Разветвленная файловая структура предполагает, что в production код будет собираться в общие файлы проекта.

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