Не нашли ответ? — Задайте вопрос команде на форуме
Подробнее о методологии БЭМ.
Можно использовать БЭМ только на уровне CSS. Для этого достаточно просто следовать рекомендациям методологии.
Поддержка браузеров
Инкапсуляция
Работа шаблонов
Вместо импорта HTML — сборка
Вместо Custom Elements — абстракция над DOM-деревом
В терминах БЭМ Bootstrap — это набор сверстанных блоков. БЭМ — не библиотека элементов интерфейса, а методология, позволяющая:
Библиотека блоков, сделанных на БЭМ — bem-components. Существуют также и другие БЭМ-библиотеки.
Исключение составляют элементы, реализация которых для упрощения разработки требует разделения на более мелкие части — подэлементы. БЭМ-методология не рекомендует создавать элементы элементов. В подобном случае вместо элемента необходимо создавать служебный блок.
Наличие элементов элементов ограничивает возможность изменять внутреннюю структуру блока: элементы нельзя поменять местами, удалить или добавить без корректировки существующего кода.
В методологии БЭМ вложенную структуру поддерживают только блоки (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>
Структура блока меняется, а правила для элементов и их названия остаются прежними.
Имя блока в именах БЭМ-сущностей обеспечивает:
Важно! Методология БЭМ допускает выбор удобной стратегии именования, но требует соблюдения консистентности в названиях. Так, например, все варианты верны: context
, ctx
или c
, attributes
, attrs
или as
. Необходимо выбрать один из них и использовать во всем проекте.
Имя блока задает пространство имен и обеспечивает уникальность имен элементов и модификаторов. Это позволяет ограничить влияние элементов и модификаторов одного блока на реализацию другого.
Микс — это совмещение разных БЭМ-сущностей на одном DOM-узле. При миксе модификатора имя блока указывает, к какому блоку применится модификатор. Если имя блока не указать, модификатор применится ко всем миксуемым БЭМ-сущностям.
Например, рассмотрим микс пункта меню (menu__item
) и кнопки (button
):
<div class="menu__item button"></div>
Добавим модификатор active
в сокращенной форме записи (без имени блока):
<div class="menu__item button active"></div>
В таком виде HTML-разметка не дает понять, к чему относится модификатор: к пункту меню (menu__item.active
) или к кнопке (button.active
). Имя блока (button_active
) явно указывает на БЭМ-сущность, к которой будет применен модификатор.
Также запись <div class="block mod">
не дает понять, какие БЭМ-сущности используются в работе. Например, из записи <div class="checkbox button">
нельзя однозначно определить, это микс модификатора и блока или микс двух блоков.
Полное имя модификатора <div class="block block_mod">
показывает, о каких сущностях идет речь: <div class="checkbox checkbox_button">
.
Явные и уникальные имена облегчают поиск необходимой сущности в коде и файловой системе.
Сравним результаты глобального поиска при отладке проекта. Найдем модификатор active
. В сокращенном виде (active
) в результаты поиска попадут все возможные комбинации и HTML-фрагменты, где встречается active
. В записи, рекомендуемой методологией, само название уже будет содержать уточняющий параметр в виде имени блока (button_active
). Так как имя модификатора уникально, в результаты поиска попадут только нужные фрагменты кода.
В БЭМ отсутствует понятие глобальных модификаторов, так как модификатор всегда относится к одной конкретной БЭМ-сущности.
Если требуется вынести CSS-свойство за пределы одного блока и применять его к разным БЭМ-сущностям в проекте, необходимо создавать отдельный блок, реализованный в технологии CSS.
БЭМ позволяет совмещать реализацию разных блоков с помощью миксов:
<div class="block1 block2"></div>
Файловая система БЭМ-проекта разделяется на вложенные директории и файлы для удобства разработки и поддержки проекта.
Придерживаться рекомендуемой структуры файловой системы не обязательно. Вы можете использовать любую альтернативную структуру проекта, соответствующую принципам организации файловой системы БЭМ, например:
flex-схема
blocks/
input/
input_layout_horiz.css
input_layout_vertical.css
input__elem.css
input.css
input.js
button/
blocks/
input/
input.css
input.js
button/
blocks/
input.css
input.js
button.css
button.js
flat-схема
blocks/
input_type_search.js
input_type_search.bemhtml
input__box.bemhtml
input.css
input.js
input.bemhtml
button.css
button.js
button.bemhtml
button.png
i-bem.js это специализированный фреймворк для разработки проектов на JavaScript в терминах блоков, элементов и модификаторв.
i-bem.js
не предназначен для замены фреймворка общего назначения, такого как jQuery.
i-bem.js
позволяет:
Ключевая идея БЭМ — независимость блоков. Вложенные селекторы увеличивают связанность кода и делают его повторное использование невозможным. Это противоречит принципам БЭМ.
Методология БЭМ допускает использование таких селекторов, но рекомендует по-максимуму его сократить.
Например, вложенность уместна, чтобы менять элементы в зависимости от состояния блока или заданной ему темы:
.nav_hovered .nav__link
{
text-decoration: underline;
}
.nav_theme_islands .nav__item
{
line-height: 1.5;
}
Комбинированные селекторы усложняют переопределение блока, так как имеют более высокую специфичность в CSS, чем одиночные. Специфичность комбинированного селектора для модификатора блока (.block1.mod
) и для переопределенного блока (.block2 .block1
) одинакова. Переопределение блока будет зависеть только от порядка объявления правил в декларации.
Рассмотрим пример:
<div class="header">
<button class="button active">
</div>
Правила модификатора active
для кнопки записываются как комбинированный селектор .button.active
. При переопределении кнопки с помощью родительского блока header
, создается селектор .header .button
. Специфичность обоих селекторов одинакова, значит применение CSS-правил определяется порядком их объявления в декларации.
Использование имени блока в названии модификатора обеспечивает более высокий приоритет CSS-правилам при переопределении блока.
Селектор .header .button
всегда будет иметь приоритет выше, чем .button_active
.
Совмещение тега и класса в селекторе повышает специфичность CSS-правил. При добавлении модификатора правила блока не смогут быть переопределены, так как специфичность селектора блока выше.
Рассмотрим пример:
<button class="button">
Записываем для него CSS-правила в селекторе button.button
.
Добавим модификатор:
<button class="button button_active">
Cелектор .button_active
не переопределит свойства блока, записанные как button.button
, так как специфичность button.button
выше. Для успешного переопределения селектор модификатора блока также должен быть скомбинирован с тегом button.button_active
.
В результате развития проекта могут появится блоки с селекторами input.button
, span.button
и, например, a.button
. В таком случае все модификаторы блока button
и вложенные в него элементы потребуют четыре разные декларации для каждого случая.
Блоки могут выражаться в HTML с помощью пользовательских тегов, к которым создаются CSS-правила. В таком случае классы можно будет использовать только для модификаторов:
<button class="mod"/>
.
Пользовательские теги могут применяться для создания селекторов к блокам, но есть ряд ограничений:
<a>
, а для полей — <input>
.Блок — независимый компонент. На него не должны влиять CSS-правила, созданные для всей страницы. Это нарушает независимость блоков и затрудняет их повторное использование.
Общий сброс стилей по сути реализуется с помощью глобальных CSS-правил, которые в большинстве случаев пишутся к селекторам на тег, что нежелательно использовать в БЭМ-проекте.
Если сбросить стили все-таки необходимо, в БЭМ это делается в каждом блоке.
Рассмотрим пример. Если в проекте блоки меню и список выражены в HTML с помощью тега <ul>
, значит каждый блок должен предоставлять сброс CSS для <ul>
. Повторов в результирующем коде можно избежать с помощью CSS-оптимизатора.
Если в проекте не используется CSS-оптимизатор, который объединяет селекторы с одинаковым набором правил, можно применить CSS-препроцессор. Тогда для каждого нового блока можно делать сброс правил, миксуя чистый код. Например, в SASS это будет выглядеть так:
.menu {
@include reset-list;
}
.menu__item {
@include reset-list-item;
}
...
.list {
@include reset-list;
}
.list__item {
@include reset-list-item;
}
Такой способ следует использовать только при отсутствии оптимизатора.
Совмещение нескольких модификаторов на одном и том же блоке (например, <div class="block_theme_christmas block_size_big">
) приведет к дублированию кода, реализующего базовую функциональность (логику и стили) блока.
grey
) на красный (red
), нужно будет изменить шаблоны и, вполне вероятно, JavaScript-код.Методология БЭМ рекомендует выбирать имена модификаторов, опираясь на семантику, а не визуальное оформление.