Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

БЭМ: миксы

В уроке о блоках мы договорились: блок не задаёт себе внешние отступы и положение. Но кто-то же должен поставить поиск в правый угол шапки! Для этого в БЭМ есть микс — несколько сущностей БЭМ на одном теге.

Что такое микс

Микс — это просто несколько классов БЭМ из разных блоков в одном атрибуте class. Самый частый случай: тег одновременно блок сам по себе и элемент родительского блока:

<style>
  .header { display: flex; align-items: center; padding: 8px 12px; background: whitesmoke; }
  .header__logo { font-weight: bold; }
  .header__search { margin-left: auto; }
 
  .search-form { display: flex; gap: 4px; }
  .search-form__input { padding: 4px 8px; border: 1px solid silver; border-radius: 4px; }
  .search-form__button { padding: 4px 10px; border: none; border-radius: 4px; background: royalblue; color: white; }
</style>
 
<header class="header">
  <span class="header__logo">Магазин</span>
  <form class="search-form header__search">
    <input class="search-form__input" placeholder="Поиск">
    <button class="search-form__button">Найти</button>
  </form>
</header>

Тег <form> — это блок search-form и элемент header__search сразу. Форма прижата вправо, хотя сама об этом ничего не знает.

Кто за что отвечает

Классы в миксе делят обязанности:

КлассОтвечает заПример свойств
блок search-formвнешний вид и содержимоеdisplay, gap, цвета
элемент header__searchместо в родителеmargin, width, grid-area

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

Один блок в разных местах

Покажем это на кнопке. Блок button одинаков, а положение задают элементы разных родителей:

<style>
  .button { padding: 6px 12px; border: none; border-radius: 6px; background: seagreen; color: white; }
 
  .card { padding: 12px; border: 1px solid silver; border-radius: 8px; max-width: 240px; margin-bottom: 8px; }
  .card__buy { display: block; width: 100%; margin-top: 8px; }
 
  .dialog { display: flex; padding: 12px; background: whitesmoke; }
  .dialog__ok { margin-left: auto; }
</style>
 
<div class="card">
  Рюкзак, 40 €
  <button class="button card__buy">Купить</button>
</div>
<div class="dialog">
  Удалить товар?
  <button class="button dialog__ok">Да</button>
</div>

В карточке кнопка растянулась на всю ширину, в диалоге прижалась вправо, а оформление у неё одно.

Микс с модификатором

В миксе можно использовать и модификаторы любой из сущностей. Например, class="button button--primary card__buy" — кнопка основного цвета, которая занимает своё место в карточке. Классов становится больше, но каждый отвечает за одну вещь.

Частая ошибка

Менять блок через каскад родителя вместо микса:

<style>
  .button { padding: 6px 12px; border: none; border-radius: 6px; background: seagreen; color: white; }
  .card .button { display: block; width: 100%; margin-top: 8px; }
  .button--wide-off { display: inline-block; width: auto; }
</style>
 
<div class="card">
  Палатка, 90 €
  <button class="button button--wide-off">Должна быть узкой</button>
</div>

Селектор .card .button сильнее одиночного модификатора, и кнопка осталась широкой — снова война специфичности. С миксом card__buy все селекторы состоят из одного класса, и такого спора не возникает.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.