Часто задаваемые вопросы
Возникли вопросы по БЭМ? Мы поможем быстро найти ответы.
Почему БЭМ?
Блоки и элементы
Зачем в именах модификаторов и элементов указывать имя блока?
Зачем создавать отдельные директории и файлы для каждого блока и технологии?
Почему не стоит создавать элементы элементов (block__elem1__elem2)?
Модификаторы и миксы
Когда создавать булевый модификатор, когда — модификатор «ключ-значение»?
Почему нельзя писать имя модификатора блока в имени элемента (block_mod__elem)?
CSS
JavaScript
У меня другой вопрос
Если вы не нашли ответ на свой вопрос, свяжитесь с нами на форуме.
В чем отличие БЭМ от OOCSS, AMCSS, SMACSS, SUITCSS?
БЭМ работает не только с CSS, но и с JavaScript.
БЭМ больше схож с Web Components, чем с перечисленными решениями для CSS.
БЭМ предоставляет комплексное решение по созданию архитектуры проекта и помогает организовать процессы разработки.
Подробнее читайте в разделе Применение методологии для решения задач веб-разработки.
В чем разница между БЭМ и Web Components?
Поддержка браузеров
Web Components не поддерживается в Safari, iOS Safari, Internet Explorer, Firefox.
БЭМ работает во всех браузерах.
Инкапсуляция
В Web Components реализована через Shadow DOM.
В БЭМ — с помощью элементов блока.
Работа шаблонов
В Web Components шаблоны всегда выполняются в браузере. Это может потребовать дополнительных решений проблем с индексацией.
В БЭМ генерация шаблона возможна на этапе разработки. Это позволяет отдавать готовый HTML. Шаблоны могут выполняться как в браузере, так и на сервере.
Web Components использует императивный принцип — интерполяцию строк.
БЭМ использует декларативный подход, который позволяет гибко управлять шаблонизацией и избегать повторений.
Вместо импорта HTML — сборка
Web Components использует импорт HTML, который работает непосредственно в браузере. Для объединения HTML-файлов используется инструмент Vulcanize.
В БЭМ используется сборка. Для объединения файлов используются сборщики: ENB, Gulp.
Вместо Custom Elements — абстракция над DOM-деревом
В Web Components используются Custom Elements. Такой подход позволяет разместить на одном DOM-узле только один компонент.
В БЭМ используется БЭМ-дерево. Такой подход позволяет размещать на одном DOM-узле несколько компонентов (БЭМ-сущностей).
Подробнее читайте в разделе про миксы.
Полезен ли БЭМ в маленьких проектах?
Методология БЭМ предоставляет правила организации веб-проектов, независимо от их размера или количества разработчиков в команде. Даже если в вашей команде два человека и вы верстаете одностраничные сайты, БЭМ позволяет:
Повторно использовать верстку
Небольшие однотипные проекты могут иметь похожую структуру. Например, посадочные страницы (landing) — разные снаружи, одинаковые внутри. Для их создания можно использовать готовые шаблоны.
В пределах одной страницы используются одинаковые блоки: несколько кнопок, выпадающих списков или меню. Их можно взять из готовой библиотеки или реализовать свою библиотеку и использовать во всех проектах.
Быстро прототипировать верстку
Прототип сайта создается из блоков. Вместо верстки в БЭМ-проекте вы сразу проектируете интерфейс из готовых блоков.
Ускорить разработку
Уровни переопределения позволяют подключать библиотеки и доопределять блоки, не зависеть от обновлений библиотеки.
БЭМ-проект можно быстро начать с шаблонного проекта project-stub или bem-express.
Не зависеть от конкретного разработчика
Одинаковая структура всех проектов, одни правила организации кода, изолированные блоки облегчают передачу кода между разработчиками.
Ускорить рефакторинг
БЭМ-проект устроен таким образом, что изменения в одном блоке можно применить ко всем блокам в проекте. При этом нет необходимости знать все возможные случаи использования этого блока.
Система именования БЭМ-сущностей позволяет вложить смысл в имена и сделать их максимально информативными для разработчика, то есть писать самодокументируемый код.
Ускорить и упростить смену дизайна за счет уровней переопределения.
Минифицировать CSS/JS даже в одностраничном проекте.
В чем разница между БЭМ и Bootstrap?
Bootstrap — это свободный набор сверстанных блоков для создания сайтов и веб-приложений.
БЭМ — это методология, позволяющая:
создавать архитектуру проекта;
разрабатывать веб-приложения независимыми блоками;
упрощать поддержку проектов.
Также существует ряд библиотек с открытым исходным кодом:
bem-components — библиотека блоков, содержащая контролы форм и другие базовые компоненты веб-интерфейса;
bem-core — библиотека блоков, предоставляющая специализированный JavaScript-фреймворк для веб-разработки.
bem-history — БЭМ-обертка над History API.
Когда создавать блок, когда — элемент?
Методология БЭМ не устанавливает строгих правил создания блоков и элементов. Многое зависит от конкретных реализаций и личных предпочтений разработчика. Выбирайте то, что подходит именно вам, учитывая рекомендации.
Как изменить внешний вид блока?
Внешний вид блока можно изменить при помощи модификаторов или миксов.
Используйте модификаторы
Если существует вероятность переиспользовать блок в данном оформлении.
Используйте миксы
Если блок имеет специфичное оформление только для данного окружения и не будет переиспользован на проекте.
Подробнее про применение миксов и модификаторов читайте в разделе Когда создавать модификатор, когда — микс?.
Зачем в именах модификаторов и элементов указывать имя блока?
Имя блока в именах модификаторов и элементов:
Обеспечивает пространство имен.
Это позволяет ограничить влияние элементов и модификаторов одного блока на другой.
Пример
<!-- Модификаторы `button_size_m` и `select_size_m` не будут влиять друг на друга. --> <div class="button button_size_m">...</div> <div class="select select_size_m">...</div>
Позволяет использовать миксы.
При использовании миксов необходимо явно указывать пространство имен для модификаторов, чтобы было ясно к какой из сущностей на данном DOM-узле относится модификатор.
Пример
<!-- Имя модификатора `button_size_m` позволяет определить, что модификатор относится к кнопке, а не к миксу — блоку `dropdown`. --> <div class="button dropdown button_size_m">...</div>
Облегчает поиск в коде.
Уникальные имена облегчают поиск сущностей в коде и файловой структуре.
Зачем создавать отдельные директории и файлы для каждого блока и технологии?
Для удобства разработки и поддержки проекта файловую структуру БЭМ-проекта разделяют на вложенные директории и файлы.
Вы можете придерживаться рекомендуемой структуры проекта или использовать любую альтернативную:
Наследуют ли элементы блока его CSS-свойства?
Да. Механизм наследования CSS-свойств в БЭМ ничем не отличается от привычного наследования.
Чтобы одинаково оформить все элементы блока, целесообразно задать CSS-правила непосредственно блоку.
Чтобы оформить элементы по-разному, CSS-правила определяют непосредственно для каждого элемента. Возникших при этом повторов в результирующем коде можно избежать с помощью CSS-оптимизатора.
Почему не стоит создавать блоки-обертки?
Абстрактные обертки не имеют никакого смысла, так как задачи, которые они решают, реализуются с помощью миксов и дополнительных элементов блока.
Подробнее читайте в разделе HTML по БЭМ.
Почему не стоит создавать элементы элементов (block__elem1__elem2)?
Наличие элементов элементов ограничивает возможность изменять внутреннюю структуру блока. Элементы нельзя поменять местами, удалить или добавить без корректировки существующего кода.
Подробнее читайте в разделе Быстрый старт.
Когда создавать модификатор, когда — микс?
Создавайте модификатор
Если нужная вам реализация может использоваться повторно и не зависит от реализации других компонентов страницы. Например, блок select
имеет модификаторы: hovered, pressed, disabled, focused, opened.
Создавайте микс
Если нужная вам реализация требуется только для данного окружения и в данном виде точно не будет переиспользована на проекте.
Например, в большинстве случаев создается микс, если:
реализуется определенная бизнес-логика проекта;
задается внешняя геометрия для данного окружения.
Когда создавать булевый модификатор, когда — модификатор «ключ-значение»?
Создавайте булевый модификатор
Если важно только наличие или отсутствие модификатора у блока, а его значение несущественно. Например, модификатор, описывающий состояние «отключен»: disabled
.
Пример
<div class="button button_disabled">...</div>
Создавайте модификатор вида «ключ-значение»
Если состояний у блока может быть несколько. Например, для описания размеров блока можно использовать модификатор size
с допустимыми значениями s
, m
и l
.
Пример
<div class="button button_size_s">...</div>
<div class="button button_size_m">...</div>
Как выбрать имя модификатора?
Выбирайте имена модификаторов, опираясь на семантику, а не на описываемые им CSS-свойства.
Пример
<!-- Неудачное имя модификатора -->
<button class="button button_background_yellow">...</button>
<!-- Удачное имя модификатора -->
<button class="button button_view_action">...</button>
Имя модификатора button_background_yellow
неудачное, потому что:
При изменении фона с желтого (
yellow
), например, на красный (red
) придется менять не только CSS-код, но и название селектора, шаблоны и, вполне вероятно, JavaScript-код.При добавлении других CSS-свойств, например,
border
,line-height
, имя модификатора перестанет соответствовать его содержанию.
Как сделать глобальные модификаторы для блоков?
В БЭМ отсутствует понятие глобальных модификаторов, так как имя любого модификатора содержит имя блока или элемента.
Если требуется вынести CSS-свойство за пределы одного блока и применять его к разным БЭМ-сущностям в проекте, необходимо создавать отдельный блок, реализованный в технологии CSS. После чего совместить реализацию разных блоков с помощью миксов.
Подробнее читайте в разделе Стилизация групп блоков.
Почему нельзя писать имя модификатора блока в имени элемента (block_mod__elem)?
Элемент — составная часть блока, а не модификатора блока. Таким образом, только имя блока может задавать пространство имен для элементов.
Это важно, потому что:
Блок может иметь много модификаторов.
Пример
<div class="button button_size_m button_theme_islands button_type_submit"> <div class="button__text">...</div> </div>
Модификатор определяет состояние блока/элемента, которое может быть изменено во время выполнения скрипта JavaScript.
Как адаптировать сайт к различным устройствам?
Существует несколько способов изменять разметку страницы на основе ширины окна браузера:
В обоих случаях необходимо определить контрольные точки (breakpoints), условия, при которых раскладка сайта меняется с одной на другую.
Media Queries
Файловая структура:
common.blocks/ button/ button.css # CSS-реализация кнопки
CSS-реализация:
@media (max-width: 767px) {
.button {
left: 0;
}
}
@media (max-width: 479px) {
.button {
right: 0;
}
}
Примечание Имена блоков должны быть достаточно общими, для того чтобы его можно было использовать более чем с одной целью. Не стоит называть блок
sidebar-left
, если при изменении ширины экрана, его позиция изменится наright
.
Переключение модификатора
Файловая структура:
common.blocks/ button/ _position/ button_position_left.css button_position_right.css button.js # JS-реализация кнопки
button_position_left.css:
.button_position_left {
left: 0;
}
button_position_right.css:
.button_position_right {
right: 0;
}
Изменение CSS-классов на DOM-узле происходит при помощи JavaScript.
Подробнее читайте в разделе Переключение модификаторов.
Можно ли совмещать теги и классы в селекторе?
Совмещение тега и класса в селекторе повышает специфичность CSS-правил. Методология БЭМ не рекомендует совмещать теги и классы в селекторе.
Подробнее читайте в разделе Совмещение тега и класса в селекторе.
Можно ли использовать вложенные селекторы?
Вложенные селекторы увеличивают связанность кода и делают его повторное использование невозможным. Методология БЭМ допускает использование таких селекторов, но рекомендует свести их к минимуму.
Подробнее читайте в разделе Вложенные селекторы.
Можно ли использовать комбинированные селекторы?
Комбинированные селекторы имеют более высокую специфичность CSS-правил, чем одиночные. Успешность переопределения таких селекторов сильно привязана к порядку их объявления. Методология БЭМ не рекомендует использовать комбинированные селекторы.
Подробнее читайте в разделе Комбинированные селекторы.
Можно ли использовать селекторы по пользовательским тегам?
В HTML блоки могут выражаться с помощью пользовательских HTML-элементов (Custom Elements) с целью:
улучшить структуру веб-страницы и добавить смысловое значение заключенному в них содержимому;
использовать селекторы по пользовательским тегам вместо селекторов по классам;
связать с HTML-элементом дополнительные данные, с которыми потом будет работать JavaScript.
Методология БЭМ за улучшение семантики веб-страниц, но не рекомендует отказываться от селекторов по классам в пользу пользовательских тегов. В случае такой замены классы можно будет использовать только для модификаторов.
Пример
HTML-реализация:
<icon-twitter class="icon_social_twitter">...</icon-twitter>
CSS-реализация:
icon-twitter {}
.icon_social_twitter {}
В таком подходе существует ряд ограничений:
невозможно использовать миксы;
не любой блок можно выразить пользовательским HTML-элементом. Например, для всех ссылок необходим тег
<a>
, а для полей —<input>
.
Почему не стоит делать общий сброс стилей (reset)?
На блоки не должны влиять CSS-правила, созданные для всей страницы. Это нарушает их независимость и затрудняет повторное использование.
Общий сброс стилей по сути реализуется с помощью глобальных CSS-правил, которые в большинстве случаев пишутся к селекторам на тег, что нежелательно делать в БЭМ-проекте.
Почему не стоит писать block_mod вместо block block_mod?
Если оставить только класс модификатора без указания класса самого блока/элемента, то все базовые CSS-свойства блока/элемента необходимо будет определить в модификаторе.
Модификатор определяет состояние блока/элемента, которое может быть изменено во время выполнения скрипта JavaScript. Таким образом, копировать базовые CSS-свойства блока придется во все его модификаторы.
Пример
<div class="button_size_m button_theme_islands button_type_submit">
<div class="button__text">...</div>
</div>
Примечание. Совмещение нескольких модификаторов на одном и том же DOM-узле приведет к дублированию кода, реализующего базовую функциональность (логику и стили) блока.
В каких случаях следует создавать вспомогательные блоки?
Методология БЭМ не устанавливает строгих правил создания блоков-хелперов. Многое зависит от конкретных реализаций и личных предпочтений разработчика. Если такой блок необходим, то можно воспользоваться миксом.
Примером вспомогательного блока в bem-core может служить блок clearfix
, а в bem-components — z-index-group
.
Зачем внешнюю геометрию и позиционирование задавать через родительский блок?
Чтобы компонент оставался независимым, CSS-свойства, которые помешают его переиспользовать в другом окружении (например, margin
и position
), задают через родительский блок.
Подробнее читайте в разделе Внешняя геометрия и позиционирование
Зачем нужен i-bem.js, если есть jQuery?
i-bem.js не предназначен для замены фреймворка общего назначения, такого как jQuery.
i-bem.js
позволяет:
разрабатывать веб-интерфейс в терминах блоков, элементов, модификаторов;
интегрировать JavaScript-код с шаблонами и CSS-правилами в стиле БЭМ;
описывать логику работы блока как набор состояний.