Этот текст устарел. Читайте новую статью вместо него.
БЭМ - это подход к web-разработке, который позволяет получить гибкий, легко изменяемый код.
БЭМ решает следующие задачи:
Разделение кода на логические составляющие (блоки и их элементы) позволяет разделить ответственность. Разные части кода страницы могут писать разные люди.
Например, один разработчик ответственнен за colorpicker (на всём проекте), другой - за компонент валидации форм, третий - за подвал сайта и т.д.
Можно оперировать частями (блоками) без погружения в то, как эти части сделаны. Блоки реализуются так, что могут работать, будучи вставленными в любое место на странице.
Сложные блоки составляются из простых согласно их логической структуре. Таким образом, каждое решение подразумевает выделение в коде множества самостоятельных частей. Это повышает вероятность повторного использования кода.
В web-технологиях финальный продукт состоит из разных технологий (например, HTML, CSS, JS). БЭМ-методология декларирует единые термины и подходы к реализации во всех применяемых технологиях.
Напрмер, JavaScript-реализации блоков не оперируют понятиями DOM-элементов, а используют следующий уровень абстрации - БЭМ-дерево.
Картинки и документация - это тоже технологии реализации блока.
Благодаря сборке страниц из блоков, в runtime попадают только действительно используемые части. Не нужно грузить лишний, неиспользуемый код.
Код, который пишет человек и код, который попадает в браузер - это не одно и то же. Первый устроен так, как удобно разрабатывать. Второй, благодаря компиляционным преобразованиям, сделан подходящим для браузера. Например, для разных браузеров можно генерировать разный код, оптимизированный конкретно для них.
Разделение слоёв "код для человека" и "код для браузера" позволяет не менять код приложения в целях оптимизации, а улучшать "компилятор", который генерирует код для браузера из БЭМ-сущностей.
Некая самостоятельная сущность, кирпичик проекта.
Блок содержит информацию о самом себе и может знать о своих детях — элементах блока.
Может использоваться сам по себе или внутри других блоков.
Пример
Блок b-search поисковой формы

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

Модификатор — это свойство блока или элемента, которое меняет внешний вид или поведение.
Модификатор имеет имя и значение. Одновременно может использоваться несколько разных модификаторов.
Пример
Модификатор блока b-search задает ему цвет фона

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

Имя блока формируется как префикс-имя-блока.
Примеры
b-menu
b-popup
i-popup
Мы используем два вида префиксов, которые позволяют определить назначение блока.
b- (от block)
Префикс блока с визуальным представлением на странице.
Пример
Попап с тенью имеет конкретное визуальное представление. Может иметь или не иметь хвостик или закрывающий крестик. Может быть разных цветов. Может отображаться в разных направлениях.

i- (от include)
Префикс абстрактного блока, который не существует сам по себе, но используется для построения других блоков.
Или префикс блока, не имеющего визуального представления и реализующего какую-то функциональность.
Пример
Блок i-popup не имеет конкретного визуального представления. Хранит в себе функциональность, на основе которой строится блок b-popup. Без блока i-popup блок b-popup не существует.

Полное имя элемента формируется так, чтобы из него можно было определить принадлежность данного элемента к конкретному блоку.
Полное имя элемента создается по схеме: b-имя-блока__имя-элмента
Примеры
b-menu__item
b-popup__content
Полное имя модификатора блока формируется так, чтобы из него можно было определить принадлежность данного модификатора к конкретному блоку. Полное имя модификатора блока создается по схеме: b-имя-блока_имя-модификатора_значение-модификатора.
Примеры
b-menu_layout_horiz
b-menu_layout_vert
b-popup_direction_up
Полное имя модификатора элемента формируется так, чтобы из него можно было определить принадлежность данного модификатора к конкретному элементу конкретного блока. Полное имя модификатора элемента создается по схеме: b-имя-блока__имя-элемента_имя-модификатора_значение-модификатора.
Примеры
b-menu__item_state_current
b-popupa__content_visibile_yes
b-popupa__content_visibile_no
Блоку/элементу добавляется модификатор и изменение блока/элемента описывается в коде этого модификатора.
Примеры
По умолчанию фон у попапа осутствует.

Добавление модификатора theme блоку b-popup добавляет ему фон.
theme=yellow добавляет фон желтого цвета:

theme=black добавляет фон черного цвета:

У блока может быть одновременно несколько модификаторов.
Примеры
Модификатор theme — отвечает за фон попапа. Модификатор direction — отвечает за направление отображения попапа.
theme=yellow и direction=left — попап желтого цвета открывается влево:

theme=yellow и direction=right — попап желтого цвета открывается вправо:

Модификатор блока может изменять структуру блока (например, добавлять/удалять элементы) или его реализацию.
Пример
Модификатор has-close=yes — добавляет элемент «закрывающий крестик». Добавляет отступы блоку, освобождая место крестика.

Блок при размещении в другом блоке может менять свой внешний вид или поведение.
Пример
Цвет текста вложенного блока меняется с зеленого на красный, если он помещен в блок с синим фоном с красными буквами.
Примеры
Переключатель языков (b-lang-switcher)

Переключатель языков (b-lang-switcher) в подвале страницы (b-foot), уменьшается размер шрифта.

Изменения создаются на следующем уровне переопределения и добавляют или изменяют функциональность блока.
Пример
Блок может выглядеть на разных проектах по-разному. При этом его общая часть лежит в одном файле (например, в репозитории фреймворка), а частная для проекта в другом (в репозитории проекта). Блок доопределяется дополнительными проектными файлами.
Модификация уровнем переопределения используется, например, в тестовом проекте bem-bl-test, где в папке blocks содержится код, доопределяющий поведение блока b-link. Это позволяет изменить основную реализацию блока (из библиотеки bem-bl) под нужды проекта.
Реализация блока состоит из набора технологий, к примеру:
Этот набор технологий может быть разным в зависимости от блока, его назначения, и удобства использования.
В файловой системе реализации в разных технологиях записаны в соответствующие файлы. Имена файлов соответствуют соглашению об именовании.
blocks/
b-menu/
_layout/
b-menu_layout_horiz.css
b-menu_layout_horiz.bemhtml
b-menu_layout_vertical.css
b-menu_layout_vertical.bemhtml
__elem/
b-menu__elem.css
b-menu__elem.bemhtml
b-menu.css
b-menu.js
b-menu.bemhtml
blocks/
b-menu/
b-menu_layout_horiz.css
b-menu_layout_horiz.bemhtml
b-menu_layout_vertical.css
b-menu_layout_vertical.bemhtml
b-menu__elem.css
b-menu__elem.bemhtml
b-menu.css
b-menu.js
b-menu.bemhtml
blocks/
b-menu/
b-menu.css
b-menu.js
b-menu.bemhtml
blocks/
b-menu_layout_horiz.css
b-menu_layout_horiz.bemhtml
b-menu_layout_vertical.css
b-menu_layout_vertical.bemhtml
b-menu__elem.css
b-menu__elem.bemhtml
b-menu.css
b-menu.js
b-menu.bemhtml
blocks/
b-menu.css
b-menu.js
b-menu.bemhtml
БЭМ-метод подразумевает реализацию блока в различных технологиях.

Реализация возможна в нескольких вариантах.
http:clubs.ya.ru/bem/replies.xml?item_no=712
В HTML-е каждая БЭМ-сущность определяется тегом и своим классом или классами.
<div class="block-name">
<i class="block-name__elem"></i>
...
</div>
<div class="block-name block-name_modifier">...</div>Можно пойти дальше и сократить использование классов, заменив теги по умолчанию на кастомные.
<copyright>
<copyright-elem>...</copyright-elem>
...
</copyright>
<copyright class="block-name_modifier">...</copyright>Каждая БЭМ-сущность должна иметь класс, чтобы при необходимости изменить или дописать или переопредлить для них CSS-свойства.
Опираясь на то, что любой блок, возможно, придется использовать повторно, т.е. блок не является уникальным, CSS-свойства для блоков и его елементов описываются только через классы.
Важно: CSS-свойства не описываются через id, а именно вот так *НЕ ПИШЕМ*:
#header {}CSS-классы для БЭМ-сущностей соответствуют полным именам этих сущностей
См. [соглашение об именовании](#naming)
Примеры именования CSS-классов
.b-popup {} // CSS-класс блока
.b-popup__content {} // CSS-класс элемента блока
.b-popupa_theme_yellow {} // CSS-класс модификатора блокаПо возможности отказываемся от Селекторов типа. Селекторы типа — селекторы, которые применяются к DOM-узлам без CSS-класса (элементо-зависимые селекторы).
Например, вот так НЕ ПИШЕМ:
p
{
color: #ccc;
}
table.news td
{
border-bottom: 1px solid #ccc;
}
.list li
{
float: left;
}Отказ от использования Селекторов типа и CSS-каскада уменьшает Reflow Time — чистое время наложения стилей на сформированный DOM.
Ссылка на запись с более подробным описанием
В JS мы также работаем в терминах "Блок-Элемент-Модификатор". DOM-представление блоков рассматривается как более низкий уровень реализации.
Допустимы блоки без DOM-представления. Обычно это блоки-хелперы.
Пример блоков без DOM-представления:
i-request // Конструктор запросов
i-request_type_ajax //Конструктор AJAX-запросовКлиентским JS-фреймворком для работы со страницей в терминах БЭМ является JS-реализация блока i-bem библиотеки bem-bl:
Одной из реализаций блока может быть его шаблон, который по входным данным строит HTML.
В бибилиотеке bem-bl в качестве шаблонной технологии используется bemhtml. Это надмножество JS-шаблонизатора xjst, написанные на нём шаблоны блоков компилируются в JavaScript и могут быть выполнены как на сервере (через Node.js), так и на клиенте (браузере).
В простейшем случае блок соответствует DOM-узлу, один к одному. Но важно понимать, что DOM-узел и блок — это не всегда одно и тоже.
Под миксом подразумевается смешивание на одном DOM-узле разных блоков и элементов.
На одном DOM-узле может быть:
Пример
Переключатель панелей имеет элементами табы (b-tabbed-pane__tabs) и панели (b-tabbed-pane__panels). Эти два элемента находятся на одном DOM-узле одновременно, что позволяет легко менять расположение элементов на странице с вертикального на горизонтальное.
Вертикальное расположение элементов

<div class="b-tabbed-pane b-tabbed-pane__tabs">
...
</div>
<div class="b-tabbed-pane b-tabbed-pane__panels">
...
</div>Горизонтальное расположение элементов

<table class="b-layout-table">
<tr>
<td class="b-layout-table__column b-layout-table__column_side_left">
<div class="b-tabbed-pane b-tabbed-pane__tabs">
...
</div>
</td>
<td class="b-layout-table__column b-layout-table__column_side_right">
<div class="b-tabbed-pane b-tabbed-pane__panels">
...
</div>
</td>
</tr>
</table>Проект, реализованный на БЭМ, состоит из одного или нескольких уровней переопределения и кода страниц.
Приведенные ниже примеры структуры не жесткие и могут быть изменены в зависимости от потребностей проекта.
Совокупность файлов, которые определяют внешний вид и поведение конкретной страницы.
Пример
pages/
index/
index.css
index.js
index.bemhtml
index.bemdecl.js
index.bemjson.js
Страница состоит из описания блоков, которые на ней используются (.bemdecl), и конкретного их расположения (.bemjson). Это исходный код страницы. Из него генерируются все необходимые для отображения файлы (.css, .js, etc)
На странице b-page используем b-menu и b-link
Пример
exports.blocks = [
{
"name": "b-page"
},
{
"name": "b-menu",
"mods": [
{
"name": "layout",
"vals": [
"horiz"
]
},
{
"name": "theme",
"vals": [
"red"
]
}
],
"elems": [
{
"name": "item",
"mods": [
{
"name": "state",
"vals": [
"current"
]
}
]
}
]
},
{
"name": "b-link"
}
]На странице b-page используем b-menu и b-link
Пример
({
block: 'b-page',
content: {
block: 'b-menu',
mods: { layout: 'horiz', theme: 'red' },
content: [
{
elem: 'item',
elemMods: { state: 'current' },
content: 'Главная'
},
{
elem: 'item',
content: {
block: 'b-link',
url: '/',
content: 'Находки'
}
},
{
elem: 'item',
content: {
block: 'b-link',
url: '/',
content: 'Поиск'
}
},
{
elem: 'item',
content: {
block: 'b-link',
url: '/',
content: 'О проекте'
}
}
]
}
})На странице b-page используем b-menu и b-link
Пример
@import url(../../bem-bl/blocks-desktop/b-menu/b-menu.css);
@import url(../../bem-bl/blocks-desktop/b-menu/item/b-menu__item.css);
@import url(../../bem-bl/blocks-desktop/b-menu/item/_state/b-menu__item_state_current.css);
@import url(../../bem-bl/blocks-desktop/blocks/b-menu/_layout/b-menu_layout_horiz.css);
@import url(../../bem-bl/blocks-desktop/b-link/b-link.css);
@import url(blocks/b-menu/_theme/b-menu_theme_red.css);На странице b-page используем b-menu и b-link
include("../../bem-bl/blocks-desktop/i-jquery/__inherit/i-jquery__inherit.js");
include("../../bem-bl/blocks-desktop/i-jquery/__identify/i-jquery__identify.js");
include("../../bem-bl/blocks-desktop/i-jquery/__is-empty-object/i-jquery__is-empty-object.js");
include("../../bem-bl/blocks-desktopery/__debounce/i-jquery__debounce.js");
include("../../bem-bl/blocks-desktop/i-jquery/__observable/i-jquery__observable.js");
include("../../bem-bl/blocks-desktop/i-bem/i-bem.js");
include("../../bem-bl/blocks-desktop/i-bem/__internal/i-bem__internal.js");
include("../../bem-bl/blocks-desktop/i-jquery/__stringify/i-jquery__stringify.js");
include("../../bem-bl/blocks-desktop/i-bem/html/i-bem__html.js");
include("../../bem-bl/blocks-desktop/i-jquery/__leftclick/i-jquery__leftclick.js");
include("../../bem-bl/blocks-desktop/i-bem/__dom/i-bem__dom.js");
include("../../bem-bl/blocks-desktop/i-bem/__dom/_init/i-bem__dom_init_auto.js");Проект состоит из уровней переопределения. Количество уровней переопределения зависит от проекта, всегда есть минимум 1 уровень.

Реализация блока может быть на нескольких уровнях. Для каждой страницы можно настроить свое используемое множество уровней. Финальная реализация блока на странице собирается со всех уровней для этой страницы.
project/
blocks/
b-head/
b-head.css
b-head.bemhtml
b-foot/
b-foot.css
b-foot.bemhtml
b-sidebar/
b-sidebar.css
b-sidebar.bemhtml
project/
blocks/
b-head/
b-head.css
b-head.bemhtml
b-foot/
b-foot.css
b-foot.bemhtml
b-page/
b-page.bemhtml
b-sidebar/
b-sidebar.css
b-sidebar.bemhtml
pages/
index/
blocks/
b-head/
b-head.css
# переопределили вид шапки на заглавной странице
about/
blocks/
b-about-text/
# добавили новый блок
b-about-text.css
b-about-text.bemhtml
project/
framework/
b-menu/
b-menu.css
b-menu.bemhtml
b-page/
b-page.css
b-page.bemhtml
blocks/
b-head/
b-head.css
b-head.bemhtml
b-foot/
b-foot.css
b-foot.bemhtml
b-page/
# переопределение шаблонов b-page из уровня framework'а
b-page.bemhtml
b-sidebar/
b-sidebar.css
b-sidebar.bemhtml
project/
framework/
b-menu/
b-menu.css
b-menu.bemhtml
b-page/
b-page.css
b-page.bemhtml
blocks/
b-head/
b-head.css
b-head.bemhtml
b-foot/
b-foot.css
b-foot.bemhtml
b-page/
# переопределение шаблонов b-page из уровня framework'а
b-page.bemhtml
b-sidebar/
b-sidebar.css
b-sidebar.bemhtml
pages/
index/
blocks/
b-head/
b-head.css
# переопределили вид шапки на заглавной странице
about/
blocks/
b-about-text/
# добавили новый блок
b-about-text.css
b-about-text.bemhtml
project/
blocks/
b-head/
b-head.css
b-head.bemhtml
b-foot/
b-foot.css
b-foot.bemhtml
b-page/
# переопределение шаблонов b-page из уровня framework'а
b-page.bemhtml
b-sidebar/
b-sidebar.css
b-sidebar.bemhtml
pages/
index/
blocks/
b-head/
b-head.css
# переопределили вид шапки на заглавной странице
about/
blocks/
b-about-text/
# добавили новый блок
b-about-text.css
b-about-text.bemhtml
themes/
black/
# не раскладываем файлы по директориям, кладем их рядом
b-head.css
b-foot.css
b-sidebar.css
yellow/
b-head.css
b-foot.css
b-sidebar.css
Реализация блока состоит из набора технологий, к примеру:
Этот набор технологий может быть разным в зависимости от блока, его назначения, и удобства использования.
Структура блока первична, а реализация блока вторична.
Пример реализации блока b-domik
Домик на странице
|
Домик в попапе
|
b-domik/
# общие файлы реализации для всех типов домика
b-domik.css
b-domik.ie.css
b-domik.js
b-domik.xsl
_type/
# папка с модификаторами для блока
b-domik_type_onpage.css # домик, прибитый на странице
b-domik_type_onpage.ie.css
b-domik_type_onpage.js
b-domik_type_onpage.xsl
b-domik_type_popup.css # домик как всплывающее окно
b-domik_type_popup.ie.css
b-domik_type_popup.js
b-domik_type_popup.xsl
__lock/
# замочек — элемент блока
b-domik__lock.css
b-domik__lock.png
b-domik__lock.xsl
_visibility/
# модификатор элемента lock, делает его видимым
b-domik__lock_visibility_visible.css
__shadow/
# тень — элемент блока
b-domik__shadow.css
b-domik__shadow.ie.css
b-domik__shadow.png
Для работы с файлами по БЭМ-методу разрабатываются специальные инструменты bem-tools. Они позволяют создавать файлы БЭМ-сущностей в различных технологиях и сборки для страниц.
Разработка ведется в репозитории bem-tools