Возникли вопросы по БЭМ? Мы поможем быстро найти ответы.
- В чем отличие БЭМ от OOCSS, AMCSS, SMACSS, SUITCSS?
- В чем разница между БЭМ и Web Components?
- В чем разница между БЭМ и Bootstrap?
- Полезен ли БЭМ в маленьких проектах?
- Когда создавать блок, когда — элемент?
- Как изменить внешний вид блока?
- Зачем в именах модификаторов и элементов указывать имя блока?
- Зачем создавать отдельные директории и файлы для каждого блока и технологии?
- Наследуют ли элементы блока его CSS-свойства?
- Почему не стоит создавать блоки-обертки?
- Почему не стоит создавать элементы элементов (block__elem1__elem2)?
- Когда создавать модификатор, когда — микс?
- Когда создавать булевый модификатор, когда — модификатор «ключ-значение»?
- Как выбрать имя модификатора?
- Как сделать глобальные модификаторы для блоков?
- Почему нельзя писать имя модификатора блока в имени элемента (block_mod__elem)?
- Как адаптировать сайт к различным устройствам?
- Можно ли совмещать теги и классы в селекторе?
- Можно ли использовать вложенные селекторы?
- Можно ли использовать комбинированные селекторы?
- Можно ли использовать селекторы по пользовательским тегам?
- Почему не стоит делать общий сброс стилей (reset)?
- Почему не стоит писать block_mod вместо block block_mod?
- В каких случаях следует создавать вспомогательные блоки?
- Зачем внешнюю геометрию и позиционирование задавать через родительский блок?
Если вы не нашли ответ на свой вопрос, свяжитесь с нами на форуме.
-
БЭМ работает не только с CSS, но и с JavaScript.
-
БЭМ больше схож с Web Components, чем с перечисленными решениями для CSS.
-
БЭМ предоставляет комплексное решение по созданию архитектуры проекта и помогает организовать процессы разработки.
Подробнее читайте в разделе Применение методологии для решения задач веб-разработки.
Поддержка браузеров
- 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 — это свободный набор сверстанных блоков для создания сайтов и веб-приложений.
БЭМ — это методология, позволяющая:
- создавать архитектуру проекта;
- разрабатывать веб-приложения независимыми блоками;
- упрощать поддержку проектов.
Также существует ряд библиотек с открытым исходным кодом:
- 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-оптимизатора.
Абстрактные обертки не имеют никакого смысла, так как задачи, которые они решают, реализуются с помощью миксов и дополнительных элементов блока.
Подробнее читайте в разделе HTML по БЭМ.
Наличие элементов элементов ограничивает возможность изменять внутреннюю структуру блока. Элементы нельзя поменять местами, удалить или добавить без корректировки существующего кода.
Подробнее читайте в разделе Быстрый старт.
Если нужная вам реализация может использоваться повторно и не зависит от реализации других компонентов страницы. Например, блок 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. После чего совместить реализацию разных блоков с помощью миксов.
Подробнее читайте в разделе Стилизация групп блоков.
Элемент — составная часть блока, а не модификатора блока. Таким образом, только имя блока может задавать пространство имен для элементов.
Это важно, потому что:
-
Блок может иметь много модификаторов.
Пример
<div class="button button_size_m button_theme_islands button_type_submit"> <div class="button__text">...</div> </div>
-
Модификатор определяет состояние блока/элемента, которое может быть изменено во время выполнения скрипта JavaScript.
Существует несколько способов изменять разметку страницы на основе ширины окна браузера:
В обоих случаях необходимо определить контрольные точки (breakpoints), условия, при которых раскладка сайта меняется с одной на другую.
Файловая структура:
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>
.
На блоки не должны влиять CSS-правила, созданные для всей страницы. Это нарушает их независимость и затрудняет повторное использование.
Общий сброс стилей по сути реализуется с помощью глобальных CSS-правил, которые в большинстве случаев пишутся к селекторам на тег, что нежелательно делать в БЭМ-проекте.
Если оставить только класс модификатора без указания класса самого блока/элемента, то все базовые 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
позволяет:
- разрабатывать веб-интерфейс в терминах блоков, элементов, модификаторов;
- интегрировать JavaScript-код с шаблонами и CSS-правилами в стиле БЭМ;
- описывать логику работы блока как набор состояний.