БЭМ
БЭМ (Блок-Элемент-Модификатор) — методология web-разработки, а также набор интерфейсных библиотек, фреймворков и вспомогательных инструментов.
Обзор
Основные понятия
«Блок», «элемент» и «модификатор» — основные термины БЭМ. Это необходимые и достаточные понятия для описания интерфейса любой сложности.
Блок
Блок — это независимый интерфейсный компонент. Блок может быть простым или составным (содержать другие блоки). При создании блока нужно обеспечивать возможность его использования в любом месте web-страницы, а также повторения в том же самом месте страницы (родительском элементе). Блок должен включать в себя всю реализацию, необходимую для представления части интерфейса, которую он выражает.
Элемент
Элемент — это составная часть блока. Элементы контекстно-зависимы: они имеют смысл только в рамках своего блока. Элемент — не обязательная составляющая блока, небольшие блоки обходятся без элементов.
Модификатор
Модификатор — это свойство блока или элемента, задающее изменения в их внешнем виде или поведении.
Модификатор может быть булевым (например, button_big
) или парой ключ-значение (например, menu_type_bullet
, menu_type_numbers
). У блока или элемента может быть несколько модификаторов одновременно.
Цель создания БЭМ
БЭМ предлагает общую семантическую модель для всех технологий, использующихся во фронтэнд разработке (HTML, CSS, JavaScript, шаблоны и др.)
Используя понятия «блок», «элемент» и «модификатор» можно описать древовидную структуру документа. Такое описание называется BEM tree и является семантическим представлением интерфейса, абстракцией над DOM tree.
Применение БЭМ в различных web-технологиях
HTML/CSS
В HTML/CSS блоки, элементы и модификаторы представлены в виде CSS-классов, названных согласно правилам именования (naming convention). Несколько блоков могут быть расположены на одном и том же DOM-узле, в этом случае DOM-узлу назначается 2 CSS-класса. На одном DOM-узле также могут быть одновременно расположены блок и элемент другого блока.
Правила именования БЭМ-классов от Яндекса
CSS-класс блока соответствует имени блока. Для разделения слов в сложных именах блоков используется дефис.
<div class="header">...</div>
<ul class="menu">...</ul>
<span class="button">...</span>
<div class="tabbed-pane">...</div>
CSS-класс элемента содержит имя блока и имя элемента, разделённые двумя знаками underscore.
<div class="header">
<div class="header__bottom">...</div>
</div>
<ul class="menu">
<li class="menu__item">...</li>
</ul>
<span class="button">
<input class="button__control">...</input>
</span>
<div class="tabbed-pane">
<div class="tabbed-pane__panel">...</div>
</div>
CSS-класс модификатора содержит имя блока и имя модификатора, разделённые одним знаком underscore. В том случае, если модификатор — это пара ключ-значение, они тоже разделяются знаком underscore. Для модификатора элемента в CSS-классе сохраняются и имя блока, и имя элемента. CSS-класс модификатора используется в паре с классом своего блока (или элемента).
<div class="header header_christmas">...</div> <!-- Christmas edition of the header -->
<ul class="menu">
<li class="menu__item menu__item_current">...</li>
</ul>
<span class="button button_theme_night">...</span>
<div class="tabbed-pane tabbed-pane_disabled">...</div>
Правила именования БЭМ-классов от Гарри Робертса
Альтернативные правила именования были предложены Гарри Робертсом[1]. Он советует использовать 2 дефиса для разделения имён блока и элементов от модификатора.
<div class="header header--christmas">...</div> <!-- Christmas edition of the header -->
<ul class="menu">
<li class="menu__item menu__item--current">...</li>
</ul>
<span class="button button--theme_night">...</span>
<div class="tabbed-pane tabbed-pane--disabled">...</div>
Префиксы
Некоторые правила именования рекомендуют использовать префиксы. Так, все классы блоков могут начинаться с префикса b-
.
<div class="b-header">...</div>
<ul class="b-menu">...</ul>
<span class="b-button">...</span>
<div class="b-tabbed-pane">...</div>
Иногда в качестве префикса используют сокращённое имя проекта. Например, OrangePool-> op.
<div class="op-header">...</div>
<ul class="op-menu">...</ul>
<span class="op-button">...</span>
<div class="op-tabbed-pane">...</div>
JavaScript
В БЭМ JavaScript работает с абстрактной структурой блоков-элементов и модификаторов, не обращаясь к лежащим за ним DOM-узлам и их CSS-классам напрямую. Кроме того, для идентификации DOM-узлов не используются дополнительные CSS-классы "специально для JavaScript". Для обеспечения такой возможности используется фреймворк или собственный набор хелперов.
Хелперы для работы с БЭМ-структурой
Так, если каждому блоку с JavaScript-функциональностью соответствует объект, его методы позволяют:
- обращаться к вложенным элементам:
// предположим, что blockObj указывает на объект блока <div class="tabbed-pane">
blockObj.elem('panel'); // возвращает элементы <div class="tabbed-pane__panel">
- работать с модификаторами
// предположим, что blockObj указывает на объект блока <div class="tabbed-pane">
blockObj.setMod('disabled'); // устанавливает модификатор <div class="tabbed-pane tabbed-pane_disabled">
blockObj.delMod('disabled'); // удаляет модификатор
Реакция на установку/удаление модификаторов
Поскольку модификатор отражает состояние блока, при назначении модификатора блок или элемент должен быть приведён в соответствующее состояние. Для изменения внешнего вида достаточно назначения CSS-класса модификатора. В более сложных случаях приведение блока в нужное состояние требует JavaScript-функциональности. Поэтому у используемого JavaScript-фреймворка должна быть возможность декларировать список действий, соответствующий модификатору.
BlockObj.on({
active: function() {
// do smth when active
},
disabled: function() {
// do something when disabled
}
});
i-bem.js
На сегодняшний день фреймворк i-bem.js
(часть библиотеки bem-core
) предлагает самую полную реализацию БЭМ-принципов в JavaScript. Информацию о фреймворке и примеры использования можно найти на страницах:
- Пошаговое руководство по i-bem.js . Дата обращения: 7 апреля 2014.
Файловая структура проекта
На файловой системе блоки, элементы и модификаторы представлены в виде файлов своих реализаций в различных web-технологиях. Файлы, относящиеся к одному блоку, объединяют в один каталог.
Плоская структура
Самая простая структура проекта не предполагает вложенности в каталоге блоков:
button/
button.css
button.js
button.tpl
button__control.css
header/
header.css
header.tpl
header_christmas.css
tabbed-pane/
tabbed-pane.css
tabbed-pane.js
tabbed-pane.tpl
Вложенная структура
В больших проектах или библиотеках удобно использовать вложенную файловую структуру блока, где для элементов и модификаторов выделяются каталоги.
button/
__control/
button__control.css
button.css
button.js
button.tpl
header/
_christmas/
header_christmas.css
header.css
header.tpl
tabbed-pane/
tabbed-pane.css
tabbed-pane.js
tabbed-pane.tpl
Применение
Методология разработана в компании Яндекс и широко используется в продуктах этой компании[2].
Она нашла применение в составе специально разработанного HTML5-фреймворка при редизайне и рефакторинге почтового сервиса mail.ru[3][4].
Эту же методологию, помимо всего прочего, использовала и телерадиокомпания Би-Би-Си при разработке своего нового сайта[5].
БЭМ также использована в таком выпущенном в 2015 году продукте Google, как Material Design Lite, HTML5-фреймворке, наподобие Twitter Bootstrap, поддерживающим Material design[6].
Примечания
- Harry Roberts. MindBEMding – getting your head ’round BEM syntax . csswizardry (25 January, 2013). Дата обращения: 7 июля 2015.
- Varvara Stepanova. What you can borrow from Yandex frontend dev . Riga WebConf, bem.info (November 2012.). Дата обращения: 7 июля 2015.
- Yury Vetrov. Product Design Unification Case Study: Mobile Web Framework . Smasing Magazine (February 4th, 2015). Дата обращения: 7 июля 2015.
- Юрий Ветров. Унификация дизайна: Фреймворк Mail.Ru Group для мобильного веба . bem.info (20 мая 2015). Дата обращения: 7 июля 2015.
- Andrew Hillel. Senior Web Developer, Content. How we built the new BBC Homepage . BBC Blog (16 February 2015). Дата обращения: 7 июля 2015.
- Understanding BEM . material-design-lite. Дата обращения: 7 июля 2015.
Литература
- Varvara Stepanova. A New Front-End Methodology: BEM . Smashing Magazine (16 апреля 2012). Дата обращения: 7 июля 2015.
- Maxim Shirshin. Scaling Down The BEM Methodology For Small Projects . Smashing Magazine (July 17th, 2014). Дата обращения: 7 июля 2015. (перевод Масштабирование наоборот: БЭМ-методология Яндекса на небольших проектах)
- Harry Roberts. MindBEMding – getting your head ’round BEM syntax . csswizardry (25 January, 2013). Дата обращения: 7 июля 2015.
- Robin Rendle. BEM 101 . css-tricks (April 2, 2015). Дата обращения: 7 июля 2015.
Ссылки
- Официальный сайт БЭМ . Дата обращения: 7 апреля 2014.
- Русскоязычный клуб разработчиков (закрыт) (недоступная ссылка). Дата обращения: 8 февраля 2015. Архивировано 21 декабря 2014 года.
- Русскоязычный форум разработчиков . Дата обращения: 8 февраля 2015.
- Официальный Twitter БЭМ . Дата обращения: 7 апреля 2014.
- Сравнение БЭМ и Каскадирования . Дата обращения: 3 июня 2016.