Мифология БЭМ

Среди разработчиков распространён миф, что БЭМ — это просто довольно некрасивый и чрезмерно длинный способ нейминга CSS-классов, который не очень-то актуален в современной разработке ввиду наличия во фронтенд-экосистеме огромного количества более удобных инструментов, полностью заменяющих его. На самом деле, это в корне неверное суждение, поскольку БЭМ — это нечто большее, чем просто нейминг, и, на мой взгляд, он может быть полезен любому веб-разработчику независимо от технического стека.
Зачем мне БЭМ, если есть «framework-name»?
Часто возникают споры о том, что лучше использовать для вёрстки: БЭМ или, например,
БЭМ — про нейминг CSS-классов
Согласно БЭМ CSS-классы действительно именуются по схеме block__element_modifier (разделители можно выбрать на свой вкус). Многие на этом заканчивают изучение этой методологии и идут писать код на Tailwind. На самом же деле нейминг — это просто один из тех самых опциональных инструментов, использования которого не достаточно для следования методологии.
/* Блок */.my-button {/* ... */}
/* Элемент */.my-button__label {/* ... */ }
/* Модификатор */.my-button_primary {/* ... */ } Такие длинные названия классов позволяют исключить использование каскада (превратив CSS в SS), что в некоторой степени упрощает жизнь, поскольку пропадает необходимость думать о
На практике же можно писать каскадные селекторы вида .block .element .modifier и продолжать следовать БЭМ, что заставит вас задумываться о каскаде и добавит риск возникновения классов с такими же названиями (инструменты вроде
Если используемый вами инструмент позволяет вам использовать более удобный на ваш взгляд нейминг, можете запросто использовать его. Например, вот так я пишу стили по БЭМ с использованием
import styled, { css } from "styled-components";
/** Модификаторы */const buttonKindStyles = { primary: css` /* ... */ `, secondary: css` /* ... */ `};
/** Блок my-button */export const MyButton = styled.button` /* ... */
/** Выбор модификатора: my-button_primary или my-button_secondary */ ${({ kind }) => buttonKindStyles|kind]}`;
/** Блок my-form */export const MyForm = styled.form` /* ... */
/** Элемент my-form__button */ ${MyButton} { /* ... */ }`;
В чём же тогда всё-таки смысл БЭМ?
БЭМ позволяет создавать более простые, изолированные и переиспользуемые компоненты, причём с точки зрения не только стилей, но и поведения.
Предположим, вы хотите разработать компонент «форма с кнопками». В кнопке необходимо наличие иконки.
Простота
Простота достигается тем, что структура «Блок-Элемент» подразумевает наличие только двух уровней вложенности.
Элементы элементов согласно БЭМ не допускаются , поэтому код кнопки придётся вынести в отдельный компонент, а значит код формы останется простым и будет решать задачи только самой формы.
Изолированность
Как уже было упомянуто, компонент формы решает только свои собственные задачи, не влияя на внутреннее устройство кнопки, но может добавлять ей новое поведение с помощью модификаторов и миксинов, что соответствует
Переиспользуемость
Кнопка, являясь отдельным компонентом не знает ничего о форме, а значит может быть использована в других компонентах.
Под словами “не знает ничего о форме” я подразумеваю, например, расположение относительно других элементов. То есть не стоит задавать внешние отступы или координаты компоненту, являющемуся блоком, поскольку этот блок может стать элементом любого другого блока, а в разных случаях вам может понадобиться по разному расположить одну и ту же кнопку.
❌ Плохо
Для самой кнопки определена внешняя геометрия (например, margin ), поэтому при использовании её в других компонентах может потребоваться их переопределять:
/** Блок my-button */export const MyButton = styled.button` margin: 16px;`;
/** Блок my-form */export const MyForm = styled.form``;
✅ Хорошо
Для кнопки по умолчанию не определена внешняя геометрия, определять её будут блоки, элементами которых будет эта кнопка:
/** Блок my-button */export const MyButton = styled.button``;
/** Блок my-form */export const MyForm = styled.form` /** Элемент my-form__button */ ${MyButton} { margin: 16px; }`;
Заключение
БЭМ, вопреки распространённому мнению, — не просто способ наименования CSS-классов, а более абстрактная методология, принципы которой применимы для любого технологического стека и не заставляют использовать конкретные инструменты.
Глубокое понимание достаточно простых принципов БЭМ позволяет писать гораздо более поддерживаемый код в любом проекте.