CSS BEM именование блоков для разных секций веб-страниц
Узнайте, как правильно применять методологию BEM для блоков, которые появляются в разных секциях страницы, и как избежать длинных классов, сохраняя чистоту кода.
Конвенции именования CSS BEM для блоков в разных секциях
Я реализую методологию BEM и у меня есть блок review, который появляется как в top-review-section, так и в product-review-section. Мой текущий подход использует модификатор для контекстно‑специфического оформления, но полученные имена классов довольно длинные. Правильно ли такой подход, или есть более подходящие альтернативы для работы с блоками BEM, которые появляются в разных секциях?
<div class="top-review-section">
<article class="review review--top-review-section">
<p class="review__content review__content--top-review-section">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper review__author-image-wrapper--top-review-section">
<img class="review__author-image" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
BEM‑методология предоставляет несколько подходов к работе с блоками, которые появляются в разных секциях, и ваш текущий подход с использованием контекстных модификаторов технически корректен, но действительно может привести к чрезмерно длинным именам классов. Ключевое — понять доступные альтернативы и выбрать наиболее подходящее решение для вашего конкретного случая.
Contents
- Understanding Your Current Approach
- Alternative BEM Solutions for Multiple Sections
- Context vs. Modifier: When to Use Each
- Practical Examples and Recommendations
- Best Practices for Scalable BEM Implementation
- Performance Considerations
Понимание вашего текущего подхода
Ваше текущее решение следует конвенции именования BEM, используя модификаторы для указания контекста:
<div class="top-review-section">
<article class="review review--top-review-section">
<p class="review__content review__content--top-review-section">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper review__author-image-wrapper--top-review-section">
<img class="review__author-image" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
Этот подход технически корректен согласно методологии BEM, где модификатор меняет внешний вид или поведение блока или элемента [source 1]. Однако, как вы заметили, он приводит к очень длинным именам классов, которые могут стать трудными для управления.
Как отмечает Markus Oberlehner, хотя этот подход работает, он может создать громоздкий CSS и HTML, которые сложно поддерживать.
Альтернативные решения BEM для нескольких секций
1. BEM‑микс
BEM‑микс объединяет разные блоки, чтобы применить стили одного блока к другому. Это часто более элегантно, чем длинные имена модификаторов.
<div class="top-review-section">
<article class="review review--top">
<p class="review__content">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper">
<img class="review__author-image" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
С CSS:
.top-review-section {
/* стили, специфичные для секции */
}
.review--top {
/* применяет стили секции «top» к блоку review */
}
Согласно Markus Oberlehner, Harry Roberts предлагает использовать BEM‑миксы, чтобы избежать стилизации конкретных контекстов, а вместо этого сосредоточиться на конкретной цели «вещи».
2. Контекстная стилизация с помощью родительских селекторов
Вместо добавления модификаторов к каждому элементу вы можете использовать родительский контейнер для ограничения стилей:
<div class="top-review-section">
<article class="review">
<p class="review__content">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper">
<img class="review__author-image" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
С CSS:
.top-review-section .review {
/* стили для review в секции top */
}
.top-review-section .review__content {
/* стили контента для секции top */
}
Этот подход сохраняет имена классов короче, но слегка повышает специфичность CSS.
3. Использование пользовательских тегов как селекторов блоков
GetBem.com предлагает использовать пользовательские теги как селекторы блоков:
<div class="top-review-section">
<article class="review">
<p class="review__content">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper">
<img class="review__author-image" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
С CSS:
top-review-section review {
/* стили для review в секции top */
}
top-review-section review__content {
/* стили контента для секции top */
}
Контекст vs. Модификатор: Когда использовать каждый
Используйте модификаторы, когда:
- Блок/элемент имеет разные состояния (active, disabled, featured)
- Блок/элемент имеет разные визуальные представления (цвета, размеры)
- Изменение является внутренним свойством блока, а не его контекста
Используйте контекст, когда:
- Стили зависят от того, где блок находится
- Вы хотите сохранить короткие имена классов
- Внешний вид блока меняется в зависимости от контейнера
Согласно официальной методологии BEM, существует четыре основных метода модификации блоков:
- Использование модификатора для изменения блока
- Использование микса для изменения блока
- Использование уровней переопределения для изменения блока
- Использование контекста для изменения блока
Практические примеры и рекомендации
Рекомендуемый подход для вашего случая
Для блока review в разных секциях я рекомендую гибридный подход:
<!-- Для секции top review -->
<div class="top-review-section">
<article class="review review--top">
<p class="review__content">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper">
<img class="review__author-image review__author-image--top" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
<!-- Для секции product review -->
<div class="product-review-section">
<article class="review review--product">
<p class="review__content">
lorem
</p>
<div class="review__author">
<div class="review__author-image-wrapper">
<img class="review__author-image" src="" alt="user profile image">
</div>
<p class="review__author-username">
lorem
</p>
</div>
</article>
</div>
С CSS:
/* Базовые стили review */
.review {
/* общие стили review */
}
.review__content {
/* общие стили контента */
}
.review__author {
/* общие стили автора */
}
.review__author-image-wrapper {
/* общие стили обёртки */
}
.review__author-image {
/* общие стили изображения */
}
/* Модификаторы, специфичные для контекста */
.review--top {
/* стили для секции top */
}
.review--product {
/* стили для секции product */
}
.review__author-image--top {
/* опционально: если изображение автора требует особой стилизации в секции top */
}
Этот подход:
- Сохраняет большинство имен классов короткими и чистыми
- Применяет модификаторы только там, где это действительно необходимо
- Сохраняет низкую специфичность, характерную для BEM
- Делает код более поддерживаемым и читаемым
Лучшие практики масштабируемой реализации BEM
-
Используйте осмысленные имена: Как рекомендует DEV Community, используйте осмысленные имена для блоков, элементов и модификаторов.
-
Сохраняйте модификаторы сфокусированными: Применяйте модификаторы только к тем элементам, которые действительно нуждаются в стилизации, специфичной для контекста, а не к каждому элементу блока.
-
Рассмотрите BEM‑миксы для сложных контекстов: Когда у вас есть несколько блоков, которым нужна похожая стилизация в контексте, рассмотрите использование BEM‑миксов вместо добавления модификаторов к каждому блоку.
-
Избегайте глубокой вложенности: CSS‑Tricks советует не создавать лишние родительские элементы, если дочерний элемент может существовать без них.
-
Используйте короткие, описательные имена модификаторов: Вместо
--top-review-sectionиспользуйте--topили--primary, если смысл ясен.
Соображения производительности
При реализации BEM в нескольких секциях учитывайте:
- Размер CSS: Длинные имена классов незначительно влияют на производительность, но громоздкий CSS может.
- Специфичность: Сохраняйте низкую специфичность, чтобы обеспечить масштабируемость BEM. Избегайте ненужного увеличения специфичности.
- Поддерживаемость: Самый важный фактор — выбор подхода, который ваша команда сможет поддерживать последовательно.
Как отмечает Smashing Magazine, ключевое — установить последовательную методологию, которая подходит для конкретных потребностей вашего проекта.
Источники
- BEM Naming Convention - Official Documentation
- BEM Block Modification Methods
- CSS, BEM and Context - Markus Oberlehner
- Understanding the CSS BEM Convention - GeeksforGeeks
- Mastering CSS with the BEM Naming Convention - DEV Community
- BEM 101 - CSS‑Tricks
- Battling BEM CSS: Common Problems - Smashing Magazine
- BEM FAQ - GetBem.com
- How to modify multiple elements of a block with BEM CSS - Stack Overflow
Заключение
Ваш текущий подход с использованием контекстных модификаторов технически корректен в рамках методологии BEM, но создает ненужно длинные имена классов, которые могут затруднить поддержку. Для более эффективного решения:
- Используйте более короткие, осмысленные имена модификаторов, например
--topвместо--top-review-section. - Применяйте модификаторы только к тем элементам, которые действительно нуждаются в стилизации, специфичной для контекста.
- Рассмотрите BEM‑миксы для сложных сценариев контекстной стилизации.
- Сохраняйте низкую специфичность CSS, избегая чрезмерной вложенности.
- Установите последовательные правила именования, которые команда сможет придерживаться.
Самый важный фактор — выбор подхода, который подходит именно вашему проекту, сохраняя при этом основные принципы модульности и переиспользуемости BEM. Подумайте о предпочтениях вашей команды, сложности проекта и долгосрочной поддерживаемости при выборе между модификаторами, контекстом или BEM‑миксами для работы с блоками в разных секциях.