Селекторы
В БЭМ не используют селекторы тегов и идентификаторов. Стили блоков и элементов описываются через селекторы классов.
Селекторы классов
Позволяют указать конкретный HTML-элемент страницы, независимо от тега. Обращение к селектору класса происходит через атрибут class
, который должен иметь каждый HTML-элемент.
Значением атрибута class
может быть разделенный пробелами список слов. Это позволяет использовать разные БЭМ-сущности на одном DOM-узле.
Пример
HTML-реализация:
<header class="header">
<!-- 'header__button' — элемент блока 'header'; 'button' — блок; 'button_theme_islands' — модификатор. -->
<button class="header__button button button_theme_islands">...</button>
</header>
Совмещение тега и класса в селекторе
Методология БЭМ не рекомендует совмещать теги и классы в селекторе. Объединение тега и класса (например, button.button
) повышает специфичность CSS-правил, что усложняет задачу их переопределения. Это приводит к войнам значимости, при которых таблицы стилей загружаются излишне сложными селекторами.
Пример
HTML-реализация:
<button class="button">...</button>
CSS-правила заданы в селекторе button.button
. Допустим, блоку добавили модификатор active
с значением true
:
<button class="button button_active">...</button>
Селектор .button_active
не переопределит свойства блока, записанные как button.button
, так как специфичность button.button
выше чем у .button_active
. Для успешного переопределения селектор модификатора блока также должен быть скомбинирован с тегом button.button_active
.
В результате развития проекта могут, например, появиться блоки с селекторами input.button
, span.button
и a.button
. В таком случае все модификаторы блока button и вложенные в него элементы потребуют четыре разные декларации для каждого случая.
Нужно стараться использовать простые селекторы классов:
.button {}
.button_active {}
Вложенные селекторы
Методология БЭМ допускает использование вложенных селекторов, но рекомендует свести их к минимуму. Вложенные селекторы увеличивают связность кода и делают его повторное использование невозможным.
Допустимые случаи использования
Вложенность уместна, если нужно изменить стили элементов в зависимости от состояния блока или заданной темы. Пример CSS-реализация: .button_hovered .buttontext { text-decoration: underline; } .button_theme_islands .buttontext { line-height: 1.5; }
Комбинированные селекторы
Методология БЭМ не рекомендует использовать комбинированные селекторы. Комбинированные селекторы (например, .button.button_theme_islands
) имеют более высокую специфичность, чем одиночные селекторы, что усложняет задачу их переопределения.
Пример
HTML-реализация:
<button class="button button_theme_islands">...</button>
CSS-правила заданы в селекторе .button.button_theme_islands
. Допустим, блоку добавили модификатор active
с значением true:
<button class="button button_theme_islands button_active">...</button>
Селектор .button_active
не переопределит свойства блока, записанные как .button.button_theme_islands
, так как специфичность .button.button_theme_islands
выше, чем у .button_active
.
Для успешного переопределения селектор модификатора блока также должен быть скомбинирован с селектором .button
и объявлен ниже .button.button_theme_islands
, так как специфичность обоих селекторов одинакова:
CSS-реализация:
.button.button_theme_islands {}
.button.button_active {}
Нужно стараться использовать простые селекторы классов:
.button_active {}
.button {}
Именование
Имя селектора должно полно и точно описывать представляемую им БЭМ-сущность.
В качестве примера рассмотрим следующие четыре строки CSS-кода:
.button {}
.button__icon {}
.button__text {}
.button_theme_islands {}
С определенной долей вероятности можно предположить, что мы имеем дело с одним блоком и его HTML-реализация выглядит следующим образом:
<button class="button button_theme_islands">
<span class="button__icon"></span>
<span class="button__text">...</span>
</button>
Сложнее сделать подобное предположение с такой группой селекторов:
.button {}
.icon {}
.text {}
.theme_islands {}
Имена icon
, text
, theme_islands
не так информативны. Общие правила именования блоков, элементов и модификаторов позволяют:
- сделать имена CSS-селекторов максимально информативными и понятными;
- решить проблему коллизии имен;
- независимо описывать стили блоков и их опциональных элементов.
Пример HTML-реализация:
<!-- Блок 'logo' -->
<div class="logo logo_theme_islands">
<img src="URL" alt="logo" class="logo__img">
</div>
<!-- Блок 'user' -->
<div class="user user_theme_islands">
<img src="URL" alt="user-logo" class="user__img">
...
</div>
Именование CSS-классов:
.logo {} /* CSS-класс блока 'logo' */
.logo__img {} /* CSS-класс элемента 'logo__img' */
.logo_theme_islands {} /* CSS-класс модификатора 'logo_theme_islands' */
.user {} /* CSS-класс блока 'user' */
.user__img {} /* CSS-класс элемента 'user__img' */
.user_theme_islands {} /* CSS-класс модификатора 'user_theme_islands' */