Только начинаю разбираться с БЭМ. Прочитал все что есть на сайте и посмотрел пару роликов, но остались вопросы на самые базовые темы. Вот один из них, касающийся способов модифицирования стилей элементов вложенных блоков:
Предположим, есть блок button:
< div class="button" > < div class="button_ _icon" / > < /div>
.button_ _icon { color: yellow; }
Он является элементом для блока panel
< div class="panel" > < div class = "button panel_ button" > < div class="button _icon" /> < /div> < /div>
Предположим, мне надо поменять цвет у button__icon только в панели, но не задеть его в остальных местах. Как это сделать правильно?
- Примиксовывать к button_ icon panel _button-icon. Это может привести к изменению кода блока button, если он не подразумевал возможность примиксовывать к иконке другие классы (например, мы используем React), что противоречит БЭМ.
- Использовать вложенный селектор .panel .button_ _icon { color: red; }. Это увеличивает связанность компонент и зависимость от реализации button'а. Ну и в обоих этих вариантах panel в принципе не должен обращаться да и знать про элементы чужого блока.
- Добавить модификатор button_ _icon_color_red для иконки. Опять же потребуется изменение кода для кнопки. И реализация сильно усложнится, если вложенность будет бОльшая - например, не во всех панелях у кнопки другой цвет, а только в панелях, которые лежат в header. Прокидывать модификатор через всю иерархию - напрягает. Как правильно?
Все варианты не противоречат БЭМ, поэтому тут лучше руководствоваться здравым смыслом. Я бы попытался определить, что влияет на цвет иконки — вложенность ли в другого родителя? Но потомкам «вредно» знать про своих «родителей», поэтому я бы завёл модификатор цвета иконки, но не для .button__icon, а для всей кнопки и отвязался бы от цвета, задав название модификатора, основываясь на функции этой кнопки (привлекать внимание, обладать другой темой, быть инвертированной или содержать только иконку), а не на качестве (что иконка именно красная):
Т.е. получается, что при появлении каждой такой задачи меняем саму кнопку, добавляя в нее новый модификатор и все соответствующие стили? Не получается ли перегруженной логика блоков? Они превращаются в такие универсальные сущности, которые всё умеют, хотя нужны только в одном месте в одном проекте.
Если используете XJST-шаблонизатор (или подобный), можно эту специфическую «логику» поместить в шаблон panel__buton и через replace() всё описать, тогда это будет и резонно, и изолировано, учитывая специфику дизайна, который диктует, что в данном случае цвет зависит от расположения.