1. 17. 16. Типовые ошибки
Last updated
Last updated
Перечислим типовые ошибки, которые совершают разработчики, когда используют БЭМ.
Определяется неверный уровень абстракции. Что это значит? Мы находим общие свойства у блоков, которые не очень похожи. Добавляем условия, чтобы скрыть лишние и показать нужные свойства у блока. Много переопределений стилей. Когда мы используем принципы KISS (Keep It Simple, Stupid) и DRY (Don’t Repeat Yourself), возникает когнитивная ошибка, и мы видим общее там, где его нет. Плохая абстракция приводит к мудрению в коде. Это попытка объединить в один блок разные сущности. Не факт, что такая композиция приживётся.
Лучше сделать несколько отдельных компонентов, чем объединить необъединимое и «подставить костыли». Пусть поначалу будет дублирование в коде, пусть мы создадим похожие блоки как разные компоненты. Потом, если появится необходимость, можно отрефакторить, увидев понятную абстракцию.
К примеру, на странице есть такие блоки:
Есть несколько блоков, которые выглядят для нас одинаково, хотя на самом деле это не так. Интуитивно хочется реализовать их как один блок, но если внимательно присмотреться, то схожими будут только шапки блоков, вот их можно выделить в один компонент.
У блока присутствует внешняя геометрия (внешние отступы, позиционирование, ширина жёстко зафиксирована). К примеру, для того, чтобы попасть в PerfectPixel, добавляют странные модификаторы для блоков.
Геометрия, в том числе и внешние отступы, могут применяться только к элементам блока. За очень редким исключением блокам задают ширину.
В этом примере нужно подняться на уровень вверх и внимательно изучить родительский блок. Подумать, почему один элемент шире, другой уже, и всё-таки определить ширину для элемента. Например, так:
Неверная декомпозиция на блоки. Не видно БЭМ-дерева, почти везде просто блок, вложенный в другой блок, и всё живёт просто благодаря тому, что имена разные. Но это не декомпозиция, это не БЭМ.
Например:
menu-item
> menu-link
> menu-text
— это отдельные блоки?
Ну, конечно же, нет, но выглядит, как будто да. Всё разбито на никак не связанные между собой блоки. Там, где должны быть элементы блока — блок__элемент
, написано просто два отдельных несвязанных блока.
А надо так:
Попытка использовать элементы элементов, допустим, так:
В примере выше для элемента, который отвечает за особое оформление первой буквы в названии компании, используется некорректное имя класса company-logo__text__first-letter
(читай как элемент first-letter
элемента text
блока company-logo
).
А надо так:
Неверное подчинение. Очень линейное БЭМ-дерево, один блок и куча элементов, нет попыток разбить, сделать декомпозицию. Например, пишут sources
> sources__logos
> sources__logo
, а могли бы sources__logos
сделать отдельным блоком, но не стали. К БЭМ не стоит подходить формально, когда синтаксис соблюдён, но при этом композиционно решено неверно, зависимости указаны неправильно, много связей и другое. План выражения выполнен, а план содержания — нет.
А надо так:
План выражения и план содержания
План выражения и план содержания — это из семиотики, науки о знаках. У любого знака, будь это картинка, символ или другой законченный знак, есть план содержания (что это значит, как это нужно понимать, какие оттенки и нюансы) и план выражения (это прозвучало-написано-нарисовано, как именно, насколько оно составное и так далее). По-другому это называется обозначаемое и обозначающее.
Термин ввёл Фердинанд де Соссюр.
Модификатор используется сам по себе, не относится ни к блоку ни к элементу. А у модификатора обязательно должен быть класс для блока или элемента!
А надо так:
Элементы без блока, которые болтаются сами по себе. Элемент обязательно должен находиться внутри блока, но элементы могут находиться «друг в друге» в разметке в рамках одного блока.
А надо так:
Названия классов включают в себя внешний вид: button--red
(кнопка красная), footer--dark
(подвал тёмный) и подобные. Лучше использовать button--primary
(кнопка первичного действия).
Возможное исключение — button--size-xl
.
Не должно быть блоков с именами uppercase
, text-center
— это стили вне блоков. Нежелательно использовать классы вида vertical-wrap
или push-md--right
. Стили должны всегда относиться к конкретному блоку. А что такое push-md--right
? Это блок такой? Нет.
Используются классы из списка запрещённых имён: for
, list__item1
, list__item2
и другие.
Разнобой в синтаксисе или нотации.
Выбираем что-то одно, к примеру, нотацию блок__элемент--модификатор
:
Ошибкой будет одновременно использовать два одинаковых модификатора с разными значениями.
В этом примере мы не можем использовать одновременно модификаторы search-form--theme-islands
и search-form--theme-lite
, search-form__button--size-s
и search-form__button--size-m
. Нужно выбрать что-то одно.
БЭМ-дерево повторяет DOM.
Например:
Блоки feature
и feature-head
называются так, как-будто они не разбиты на части и каждый зависит от другого. Такая декомпозиция на компоненты похожа на попытку спрятать элементы элементов и повторить DOM.
Если шапка, действительно, это часть блока feature
, пусть она будет его элементом, например, так:
Если этот блок может существовать сам по себе, в том числе и в других блоках, тогда надо так:
Добавление дополнительных имён классов-блоков, а не модификаторов.
Чтобы добавить визуальное отличие для базового блока делают его композицией из двух блоков, например: class="section support"
, class="section advantages"
.
А надо так: class="section section--support"
, class="section section--advantages"
.
Но классы также могут примиксоваться и как блоки, всё зависит от ситуации.
Использование модификаторов вместо элементов. Модификатор — это всегда только внешнее изменение для блока/элемента.
Например:
А надо так:
Формально это не ошибка, но будут проблемы, когда компонуют блоки так: list-item > service-menu__item > footer__link
. Так-то можно «взболтать, но не смешивать», однако при этом не получится поменять стили только в одном месте, в конкретном блоке. Стили сменятся во всех блоках, где их используют.
Например, вот такой микс:
Блоки не должны «вплетаться» друг в друга. В такой разметке не учитывается один момент: как их использовать по отдельности и где тут внутри чья зона ответственности?
А надо так:
Блок хочет управлять CSS-свойствами вложенных блоков. К примеру, при использовании светлой темы цвет текста на панели с закладками должен быть #2e2c9c
, а фоновый цвет вкладок — #eeeeee
.
Устанавливаем цвет шрифта для закладок:
Задаём фоновый цвет самим вкладкам:
Используется межблочный каскад, что категорически не рекомендуется делать. Это делает код разных блоков связанным.