Путаница с модификаторами BEM

Я начал использовать методологию BEM при написании моего CSS, и было несколько случаев, когда я изо всех сил старался найти лучший способ сделать что-то конкретное.

Я хотел бы рассмотреть простой пример панели.

Предположим, что я пишу компонентный компонент CSS с использованием стиля BEM. Поэтому мой CSS может выглядеть следующим образом:

.panel {}

.panel__titlebar {}

.panel__content { display: none; }

Панель может быть либо бесцветной, либо хромированной. Поэтому я определяю еще один класс модификатора для панели:

.panel--with-chrome {
 border: 4px solid black;
 border-radius: 4px;
}

Теперь скажем, панель может находиться в полноэкранном/максимизированном состоянии, в котором исчезают хром и заголовок. Вместо определения модификаторов для панели и заголовка было бы разумно определить модификатор только на родительском (например, на панели - полноэкранный), и элементы отдыха должны соответственно измениться. Итак, теперь мой CSS становится:

.panel--fullscreen {
 /* something has to be done here */
}

.panel--fullscreen .panel__titlebar { display: none; }

Чтобы удалить хром в полноэкранном режиме, я могу либо:

  • переключить класс - с-хром в JS вместе со панелью - полноэкранный класс

  • перезаписать хром CSS внутри класса - полноэкранного.

Во-первых, это не хорошо, потому что в идеале я хотел бы просто переключить только один класс (.panel - fullscreen) в JS для переключения полноэкранного режима.

И второй плохой, потому что мне придется перезаписать предыдущий CSS, что является плохой практикой.

Так что лучший способ сделать это? Цените свои комментарии.

Спасибо

Ответ 1

Ответ зависит от многих вещей.

Во-первых, сколько логики и внешнего вида имеют модификаторы "panel-with-chrome" и "panel-fullscreen". А также о том, что это за эта логика.

Если "panel-with-chrome" приносит много свойств CSS и специальных функций JS, я бы переключил их на JavaScript при применении "panel - fullscreen".
Это также зависит от используемой вами структуры JavaScript. В "i-bem.js", который мы используем в Yandex, легко реагировать на добавление модификатора:

Но если используемая вами фреймворк не позволяет выразить такую ​​реакцию, этот ответ не будет работать так хорошо для вас.

В другом случае, когда "panel-with-chrome" имеет не очень много свойств и не привносит какую-либо логику JavaScript на страницу, я бы переопределил эти свойства CSS в классе "panel-fullscreen".

Подводя итог, нет универсального решения и строгих правил. Вы должны решить, что будет полезно в вашем случае. Решение должно зависеть от многих вещей:

  • если вы ожидаете, что ваш проект будет сохранен в будущем, какое решение будет легче поддерживать?
  • возможности используемой структуры JavaScript
  • производительность
    Не в этом конкретном случае, но иногда мы измеряем скорость рендеринга для вариантов, которые мы выбираем.
  • мнение других ребят, если вы работаете в команде
  • файловая структура вашего проекта
    Мы, здесь, в Yandex, храним CSS и JavaScript для блока в той же папке блока. Таким образом, не стоит делиться логикой между CSS и JavaScript, поскольку все они находятся в одном месте.
    Но если вы храните свои файлы JavaScript отдельно, это может повлиять на то, насколько удобно поддерживать общую логику.

И так далее...

Ответ 2

Id - первый вариант; вы все-таки переключаете состояние, поэтому вам нужно соответственно добавлять/удалять/переводить классы. Это лучше, чем отменить загрузку материала в CSS IMO.