Урок 45. Теория: БЭМ: block__element--modifier

📁 Раздел: Организация CSS ⏱️ Время изучения: ~70 мин 🎯 Сложность: Средняя
#main

⚡ Кратко

БЭМ — соглашение об именах CSS-классов, чтобы компонент был переносимым и не зависел от места на странице.

  • Block — самостоятельный компонент: .card, .menu, .form.
  • Element — часть блока, через два подчёркивания: .card__title, .menu__item.
  • Modifier — вариант вида или состояния, через два дефиса: .card--featured, .button--primary.
  • Полный формат: block__element--modifier. Модификатор добавляется рядом с базовым классом, а не заменяет его.
  • Все селекторы — один класс: специфичность плоская, переопределять легко.

Главная идея

БЭМ (Block — Element — Modifier) — это методология именования CSS-классов. Её цель — сделать так, чтобы по одному имени класса было понятно, что это за деталь интерфейса и к чему она относится, а сам компонент можно было перенести в любое место страницы без поломок. Имя строится из трёх частей: block__element--modifier.

  • Block — самостоятельный, осмысленный сам по себе компонент: card, menu, form. Его можно вынуть и поставить в другое место — он не зависит от родителя.
  • Element — часть блока, которая отдельно не имеет смысла. Пишется через два подчёркивания: card__title, menu__item, form__field.
  • Modifier — вариант вида или состояния блока/элемента. Пишется через два дефиса: card--featured, button--primary, menu__item--active. Модификатор не заменяет базовый класс, а ставится рядом с ним.

БЭМ — как почтовый адрес. Block — это дом (card): целая постройка, которую можно найти в городе. Element — квартира в этом доме (card__title): сама по себе «квартира №5» без дома бессмысленна, она существует только внутри. Modifier — пометка-статус на двери (card--featured): «квартира с ремонтом», «занято/свободно». Пометка не превращает квартиру в другую квартиру — она лишь уточняет её состояние. По полному адресу дом__квартира--статус ты всегда понимаешь, о чём речь, не глядя на соседние здания.

Как читается имя класса

Разделители подобраны так, чтобы их было легко различить глазом: блок и элемент — двойное подчёркивание __, основа и модификатор — двойной дефис --. Вот дерево одного компонента:

.card Block .card__title .card__button Element .card--featured .card__button--primary Modifier
Block .card → его Element'ы (__title, __button) → Modifier'ы (--featured, --primary) на блоке и на элементе.

Как это работает

Каждый видимый кусок интерфейса описывается ровно одним классом. Стиль вешается на этот класс, а не на его положение в дереве. Поэтому селекторы остаются плоскими (специфичность 0,1,0 у всех), и переопределить любой из них тривиально — не нужно «перебивать» длинные цепочки .sidebar .card h2.

📄 lesson-45/styles.css
/* block */
.course-card {
  display: grid;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;
}

/* modifier блока — вариант вида */
.course-card--featured {
  border-color: var(--color-accent);
}

/* element */
.course-card__title {
  margin: 0;
  font-size: 1.5rem;
}

/* element */
.course-card__button {
  justify-self: start;
}

/* modifier элемента */
.course-card__button--primary {
  color: white;
  background: var(--color-accent);
}

Правила и когда применять

  • Не привязывайте стиль к месту на странице: .sidebar .card h2 хуже, чем .card__title.
  • Modifier описывает состояние или вариант, а не новую сущность. Новая сущность — это новый блок.
  • БЭМ не требует глубокой вложенности: чаще достаточно одного класса на элемент.
  • Применяйте БЭМ, когда верстаете переиспользуемые компоненты или работаете в команде — плоские имена снимают конфликты специфичности и делают код предсказуемым.
Частая ошибка: писать элемент элемента — .card__body__title. БЭМ плоский: элемент именуется относительно блока, а не другого элемента. Правильно — .card__title, даже если в разметке заголовок лежит внутри .card__body.

Навигация