BEM методология: как организовать CSS-код и избежать хаоса

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Верстальщики и веб-разработчики, желающие улучшить свои навыки в CSS
  • Новички в области веб-разработки, интересующиеся правильными методологиями
  • Разработчики, работающие над крупными проектами и стремящиеся структурировать и упростить свой код

    Каждый верстальщик рано или поздно сталкивается с хаосом в CSS: специфичность стилей зашкаливает, классы дублируются, а модификация одного элемента неожиданно ломает вёрстку на другом конце сайта. BEM методология — это не просто способ именования классов, а целая философия организации фронтенд-кода, которая превращает беспорядочные стили в структурированную систему. В этом руководстве мы разберём каждый аспект BEM с реальными примерами кода, чтобы вы могли внедрить эту методологию в свои проекты и забыть о CSS-кошмарах навсегда. 🚀

Думаете о карьере в веб-разработке и хотите сразу учиться правильным подходам? Обучение веб-разработке от Skypro включает не только основы HTML и CSS, но и современные методологии вроде BEM. Вместо того чтобы годами нарабатывать этот опыт методом проб и ошибок, вы получите структурированные знания от практикующих разработчиков, которые ежедневно используют BEM в реальных проектах.

Что такое BEM методология и почему её стоит использовать

BEM (Block Element Modifier) — это методология разработки, предложенная компанией Яндекс для создания масштабируемого и поддерживаемого CSS кода. По сути, это подход к именованию классов и организации компонентов интерфейса, который решает распространённые проблемы верстальщиков.

В основе BEM лежит компонентный подход, который предполагает разделение интерфейса на независимые блоки. Этот принцип позволяет создавать интерфейсы из готовых компонентов и повторно использовать существующий код.

Александр Петров, ведущий frontend-разработчик

Когда я пришёл в свой первый проект, код CSS был настоящим кошмаром. Стили накладывались друг на друга, непонятно было, какой класс за что отвечает, и любое изменение требовало часов отладки. Помню, как однажды нам нужно было просто изменить цвет кнопки в одном месте, а в результате поломалась вёрстка в трёх других разделах.

Тогда я предложил команде перейти на BEM. Первые две недели все ворчали из-за "странных длинных названий классов", но когда мы закончили рефакторинг ключевых компонентов, произошло чудо. Новые фичи стали внедряться в два раза быстрее, конфликты стилей практически исчезли, а новичкам в команде требовалось значительно меньше времени на погружение в проект.

Преимущества использования BEM методологии:

  • Модульность — каждый блок интерфейса существует независимо
  • Повторное использование — компоненты можно переиспользовать в разных частях проекта
  • Улучшенная читаемость — по классу легко понять, что это за элемент и к чему относится
  • Простота масштабирования — новые компоненты легко добавляются без влияния на существующие
  • Упрощение работы в команде — все разработчики следуют единому подходу
Проблема без BEM Решение с BEM
Каскадные конфликты Плоская структура специфичности
Сложное переиспользование стилей Модульные независимые блоки
Трудности при изменении кода Предсказуемое влияние изменений
Проблемы при работе в команде Единый стандарт именования

BEM особенно полезна в крупных проектах с множеством компонентов, но даже в небольших сайтах она поможет избежать хаоса в CSS и сделать код более поддерживаемым в долгосрочной перспективе.

Пошаговый план для смены профессии

Структура BEM: блоки, элементы и модификаторы в деталях

Название BEM расшифровывается как Block (Блок), Element (Элемент), Modifier (Модификатор) — это три ключевых понятия методологии, которые определяют структуру вашего интерфейса. Давайте разберём каждое из них подробнее. 🧩

Блок (Block) — это независимый компонент интерфейса, который может быть повторно использован. Блок можно представить как законченный кусок интерфейса, который имеет свой собственный смысл. Примеры блоков: шапка, меню, поисковая форма, кнопка, карточка товара.

Особенности блока:

  • Блок имеет уникальное имя в пределах проекта
  • Блок может содержать другие блоки
  • Блок не зависит от окружения, его можно перемещать по странице
  • Имя блока описывает его назначение, а не внешний вид

Элемент (Element) — это составная часть блока, которая не может использоваться отдельно от него. Элементы всегда принадлежат блоку и выполняют конкретную функцию внутри него. Например, в блоке «меню» элементами могут быть пункты меню, в блоке «форма» — поля ввода, кнопки отправки и т.д.

Особенности элемента:

  • Элемент всегда является частью блока, а не другого элемента
  • Элемент не может существовать вне контекста своего блока
  • Имя элемента описывает его назначение внутри блока

Модификатор (Modifier) — это флаг на блоке или элементе, который изменяет его внешний вид, состояние или поведение. Модификаторы позволяют создавать вариации одного и того же компонента без дублирования кода.

Типы модификаторов:

  • Булевые модификаторы: просто указывают на наличие/отсутствие свойства (disabled, focused, checked)
  • Ключ-значение: указывают конкретное значение свойства (sizelarge, themedark, color_red)

Мария Соколова, технический директор

Наша команда разрабатывала UI-библиотеку компонентов для крупного финтех-проекта. Изначально у нас был классический подход с вложенными селекторами, и каждый компонент был прочно связан со своим окружением.

Когда бизнес начал требовать быстрой разработки новых интерфейсов, мы осознали, что наша система не масштабируется. Переход на BEM был болезненным, но необходимым шагом. Мы начали с декомпозиции интерфейса на блоки: "card", "button", "input", "modal", и выделили внутри них элементы вроде "cardtitle", "cardimage".

Настоящий "aha-момент" произошел, когда мы добавили модификаторы. Теперь вместо создания новых стилей для каждой вариации, мы просто добавляли класс "buttonsizelarge" или "inputstateerror". Количество кода сократилось вдвое, а скорость разработки новых экранов увеличилась втрое. Самое удивительное — новые разработчики понимали нашу структуру за день, а не за неделю, как раньше.

Взаимосвязь компонентов BEM можно представить в виде простой схемы:

Уровень Пример класса Применение
Блок button Самостоятельный компонент
Элемент button__icon Часть блока (иконка внутри кнопки)
Блок с модификатором button_size_large Вариация блока (большая кнопка)
Элемент с модификатором button__icon_position_left Вариация элемента (иконка слева)

Понимание этих базовых компонентов и их взаимодействия — ключ к успешному применению BEM методологии. Правильная декомпозиция интерфейса на блоки, элементы и модификаторы закладывает фундамент для масштабируемой и поддерживаемой архитектуры CSS.

Правила именования классов по BEM: синтаксис и конвенции

Одно из главных преимуществ BEM — строгие правила именования классов, которые делают код предсказуемым и понятным. Эти правила формируют единую систему, позволяющую по имени класса сразу понять его роль и положение в структуре. 📝

Синтаксис BEM имеет следующий формат:

  • Блок: block-name
  • Элемент: block-name__element-name (двойное подчеркивание разделяет имя блока и элемента)
  • Модификатор (булевый): block-name_modifier или block-name__element-name_modifier
  • Модификатор (ключ-значение): block-name_key_value или block-name__element-name_key_value

Рассмотрим конкретные примеры именования:

Пример блока: header, menu, search-form

Пример элементов: menu__item, search-form__input, header__logo

Пример модификаторов:

  • Булевые: menu__item_current, button_disabled
  • Ключ-значение: menu_theme_dark, button_size_large, search-form__input_type_text

Важные правила и рекомендации по именованию классов в BEM:

  1. Используйте только латинские буквы, цифры и дефис для имен
  2. Имена должны быть понятными и описывать назначение, а не внешний вид
  3. Названия блоков должны быть уникальными в рамках проекта
  4. Избегайте создания элементов элементов (например, menu__item__icon неправильно)
  5. Если элемент может использоваться отдельно, лучше сделать его блоком
  6. Используйте модификаторы для состояний и вариаций, а не создавайте новые блоки

Существует несколько вариаций синтаксиса BEM. Стандартный (канонический) синтаксис использует двойное подчеркивание для элементов и одинарное для модификаторов. Однако есть и альтернативные варианты:

Синтаксис Блок Элемент Модификатор
Классический BEM block block__element block_modifier<br>block__element_modifier
Two Dashes (2Dashes) block block__element block--modifier<br>block__element--modifier
CamelCase Block Block-Element Block--modifier<br>Block-Element--modifier
React-стиль Block Block__element is-modifier (отдельный класс)

Вот пример корректного именования классов в HTML:

HTML
Скопировать код
<form class="search-form search-form_theme_dark">
<input class="search-form__input search-form__input_type_text">
<button class="search-form__button search-form__button_disabled">
<span class="search-form__button-text">Найти</span>
<img class="search-form__button-icon">
</button>
</form>

В этом примере:

  • search-form — блок
  • search-form_theme_dark — блок с модификатором ключ-значение
  • search-form__input, search-form__button — элементы блока
  • search-form__input_type_text — элемент с модификатором ключ-значение
  • search-form__button_disabled — элемент с булевым модификатором

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

Практическое применение BEM в CSS: организация стилей

Правильная организация CSS-кода — одно из ключевых преимуществ BEM методологии. В этом разделе мы рассмотрим, как структурировать ваши стили в соответствии с принципами BEM, чтобы избежать конфликтов и сделать код более поддерживаемым. 💅

Основной принцип CSS в BEM — это избегание вложенных селекторов и использование только классов. Это позволяет избежать проблем со специфичностью и сделать стили модульными.

Вот основные принципы организации CSS в BEM:

  1. Плоская структура селекторов — каждый селектор имеет одинаковую специфичность
  2. Независимость блоков — стили одного блока не должны влиять на другие
  3. Стили привязаны только к классам — не используйте селекторы тегов или идентификаторов
  4. Минимум каскада — избегайте вложенных селекторов

Рассмотрим, как это выглядит на практике:

CSS
Скопировать код
/* Стили блока */
.card {
width: 300px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 20px;
}

/* Стили элементов */
.card__title {
font-size: 18px;
margin: 0 0 10px;
}

.card__image {
width: 100%;
height: auto;
}

.card__description {
font-size: 14px;
line-height: 1.5;
}

/* Стили модификаторов блока */
.card_featured {
border-color: #f0c14b;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.card_theme_dark {
background: #333;
color: #fff;
}

/* Стили модификаторов элементов */
.card__title_size_large {
font-size: 24px;
}

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

Структурировать CSS-файлы при использовании BEM можно несколькими способами:

1. Один файл для всего проекта — подходит для небольших проектов:

CSS
Скопировать код
/* styles.css */
/* Блок header */
.header { ... }
.header__logo { ... }
.header__nav { ... }

/* Блок button */
.button { ... }
.button_size_large { ... }
.button__icon { ... }

2. Разделение по блокам — каждый блок в отдельном файле, подходит для средних проектов:

CSS
Скопировать код
/* blocks/header.css */
.header { ... }
.header__logo { ... }
.header__nav { ... }

/* blocks/button.css */
.button { ... }
.button_size_large { ... }
.button__icon { ... }

3. Полное разделение — для крупных проектов, каждый блок, элемент и модификатор в отдельных файлах:

CSS
Скопировать код
/* blocks/header/header.css */
.header { ... }

/* blocks/header/__logo/header__logo.css */
.header__logo { ... }

/* blocks/button/button.css */
.button { ... }

/* blocks/button/_size/button_size_large.css */
.button_size_large { ... }

При работе с препроцессорами вроде SASS или LESS, BEM хорошо сочетается с функциональностью вложенных селекторов, но важно использовать их правильно:

scss
Скопировать код
.card {
width: 300px;
border: 1px solid #ddd;

&__title {
font-size: 18px;
}

&__image {
width: 100%;
}

&_featured {
border-color: #f0c14b;
}
}

Такая запись генерирует плоскую структуру селекторов в итоговом CSS, сохраняя все преимущества BEM, но делая код более лаконичным.

Важные рекомендации по организации CSS в BEM:

  • Используйте только классы, избегайте селекторов по тегам и ID
  • Не используйте каскад для стилизации элементов внутри блока
  • Храните все модификаторы рядом с базовыми стилями блока или элемента
  • Не используйте !important — при правильной организации BEM он не нужен
  • Группируйте свойства внутри селекторов по логическим категориям (позиционирование, размеры, типографика и т.д.)

Реальные примеры BEM верстки: от простого к сложному

Теория — это хорошо, но настоящее понимание BEM приходит через практику. В этом разделе мы рассмотрим реальные примеры верстки компонентов разной сложности с использованием BEM методологии. 🛠️

Пример 1: Простая кнопка

Начнем с самого простого компонента — кнопки с различными состояниями и модификаторами:

HTML
Скопировать код
<!-- HTML -->
<button class="button button_size_medium button_type_primary">
<span class="button__text">Отправить</span>
</button>

<button class="button button_size_large button_type_secondary button_disabled">
<span class="button__icon"></span>
<span class="button__text">Сохранить</span>
</button>

CSS
Скопировать код
/* CSS */
.button {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 4px;
font-family: Arial, sans-serif;
cursor: pointer;
transition: all 0.2s;
}

/* Модификаторы размера */
.button_size_medium {
height: 36px;
padding: 0 16px;
font-size: 14px;
}

.button_size_large {
height: 48px;
padding: 0 24px;
font-size: 16px;
}

/* Модификаторы типа */
.button_type_primary {
background-color: #4a90e2;
color: white;
border: none;
}

.button_type_secondary {
background-color: transparent;
color: #4a90e2;
border: 1px solid #4a90e2;
}

/* Состояние */
.button_disabled {
opacity: 0.5;
cursor: not-allowed;
}

/* Элементы */
.button__text {
font-weight: 500;
}

.button__icon {
width: 16px;
height: 16px;
margin-right: 8px;
background-size: contain;
}

Пример 2: Карточка товара

Теперь рассмотрим более сложный компонент — карточку товара в интернет-магазине:

HTML
Скопировать код
<!-- HTML -->
<div class="product-card product-card_featured">
<div class="product-card__image-container">
<img class="product-card__image" src="product.jpg" alt="Product">
<span class="product-card__badge product-card__badge_type_sale">-20%</span>
</div>

<div class="product-card__content">
<h3 class="product-card__title">Беспроводные наушники WH-1000XM4</h3>
<div class="product-card__price-container">
<span class="product-card__price product-card__price_discounted">21 990 ₽</span>
<span class="product-card__price-original">27 990 ₽</span>
</div>
<div class="product-card__rating">
<span class="product-card__stars">★★★★☆</span>
<span class="product-card__reviews-count">(42)</span>
</div>
</div>

<div class="product-card__actions">
<button class="product-card__button product-card__button_type_primary">В корзину</button>
<button class="product-card__button product-card__button_type_secondary">В избранное</button>
</div>
</div>

CSS
Скопировать код
/* CSS */
.product-card {
width: 300px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.3s, box-shadow 0.3s;
}

.product-card_featured {
border: 1px solid #f0c14b;
}

.product-card__image-container {
position: relative;
height: 200px;
}

.product-card__image {
width: 100%;
height: 100%;
object-fit: cover;
}

.product-card__badge {
position: absolute;
top: 10px;
right: 10px;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
}

.product-card__badge_type_sale {
background-color: #e53935;
color: white;
}

.product-card__badge_type_new {
background-color: #43a047;
color: white;
}

.product-card__content {
padding: 15px;
}

.product-card__title {
font-size: 16px;
margin: 0 0 10px;
line-height: 1.3;
}

.product-card__price-container {
display: flex;
align-items: center;
margin-bottom: 10px;
}

.product-card__price {
font-size: 18px;
font-weight: bold;
}

.product-card__price_discounted {
color: #e53935;
}

.product-card__price-original {
font-size: 14px;
color: #999;
text-decoration: line-through;
margin-left: 8px;
}

.product-card__rating {
display: flex;
align-items: center;
margin-bottom: 15px;
}

.product-card__stars {
color: #f0c14b;
}

.product-card__reviews-count {
font-size: 12px;
color: #757575;
margin-left: 5px;
}

.product-card__actions {
display: flex;
padding: 0 15px 15px;
}

.product-card__button {
flex: 1;
padding: 8px 0;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: background-color 0.2s;
}

.product-card__button_type_primary {
background-color: #4a90e2;
color: white;
border: none;
margin-right: 8px;
}

.product-card__button_type_secondary {
background-color: transparent;
color: #4a90e2;
border: 1px solid #4a90e2;
}

Пример 3: Комплексный компонент — форма поиска с автодополнением

Теперь рассмотрим более сложный интерактивный компонент:

HTML
Скопировать код
<!-- HTML -->
<div class="search search_expanded search_theme_light">
<div class="search__input-wrapper">
<input type="text" class="search__input" placeholder="Поиск...">
<button class="search__clear-button search__clear-button_hidden">×</button>
<button class="search__submit-button">
<span class="search__submit-icon"></span>
</button>
</div>

<div class="search__dropdown">
<div class="search__section">
<h4 class="search__section-title">Популярные запросы</h4>
<ul class="search__suggestions-list">
<li class="search__suggestion search__suggestion_trending">смартфоны</li>
<li class="search__suggestion">беспроводные наушники</li>
<li class="search__suggestion">умные часы</li>
</ul>
</div>

<div class="search__section">
<h4 class="search__section-title">История поиска</h4>
<ul class="search__suggestions-list">
<li class="search__suggestion search__suggestion_history">
ноутбук
<button class="search__suggestion-remove">×</button>
</li>
<li class="search__suggestion search__suggestion_history">
планшет
<button class="search__suggestion-remove">×</button>
</li>
</ul>
</div>
</div>
</div>

В приведенных примерах видно, как BEM методология позволяет создавать модульные и гибкие компоненты разной сложности. От простой кнопки до сложной формы с множеством состояний — принципы остаются одинаковыми:

  • Компоненты разделены на независимые блоки
  • Элементы описывают составные части блока
  • Модификаторы определяют вариации и состояния

Следуя этим принципам, вы сможете создавать масштабируемые и поддерживаемые компоненты любой сложности.

BEM методология — это не просто способ именования классов, а философия организации CSS и HTML, которая решает фундаментальные проблемы веб-разработки. Внедрив BEM в свой рабочий процесс, вы получите предсказуемый, модульный и легко поддерживаемый код, который будет расти вместе с вашим проектом без увеличения сложности. Начните с малого — попробуйте применить BEM к одному компоненту вашего сайта, и вы почувствуете разницу. Постепенно расширяйте область применения, и вскоре ваш CSS-код станет вашим союзником, а не источником головной боли.

Загрузка...