Условный CSS на основе класса внешнего модификатора - хорошая практика?

9

Введение / история вопроса: компоненты CSS

Для относительно большого сайта мы работаем с SASS и пытаемся управлять CSS в компонентах. Основная идея компонентов заключается в том, что компонент должен выглядеть одинаково везде, независимо от элементов контейнера, расположенных дальше в DOM.

Итак, мы хотим избежать таких вещей (SASS):

// User picture component.
.user-picture {
  img {..}
}

// Override user picture for the frontpage.
body.page-front .user-picture img {..}

Вместо этого, если мы хотим, чтобы изображение пользователя на главной странице выглядело иначе, это должен быть другой компонент. Например, с наследованием SASS или с миксином:

// User picture component.
.user-picture {
  img {..}
}

// User picture on frontpage.
.user-picture-front {
  @extend .user-picture;
  img {..}
}

Затем нам нужно настроить HTML на главной странице, чтобы он использовал другую версию пользовательского изображения.

Все идет нормально. Я разместил выше в качестве иллюстрации моего текущего понимания того, что такое компоненты CSS.

Вопрос: классы модификаторов - хорошая практика?

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

Это как-то выходит за пределы компонентов: у того же компонента по умолчанию должен быть темный текст, но белый текст, если он находится внутри контейнера с темным фоном.

Итак, у нас есть замечательная идея:

// Generic modifier class for all dark-background containers.
.white-on-black {
  // Generic text color change.
  color: white !important;
}

// Component.
.my-component {
  border: 1px solid blue;
  // Special for white-on-black.
  .white-on-black & {
    border-color: yellow;
  }
}

Таким образом, у нас есть внешний класс «модификатор» или «контекст», white-on-blackкоторый изменяет способ отображения внутренних элементов.

Мотивация заключается в том, что сам компонент не отвечает за фон элемента контейнера, находящегося дальше в DOM.

Это работает. Единственная проблема в том, что у нас есть контейнер с белым фоном внутри контейнера с темным фоном. Но это в стороне, это работает хорошо.

Вопрос в том, является ли это хорошей практикой с точки зрения архитектуры, когда мы пытаемся сохранить компоненты независимыми друг от друга.

Альтернативой было бы иметь другой компонент, например my-component-on-dark-bg, который наследуется my-componentи имеет другой цвет для текста и границ. Но здесь (например, PHP) код, который создает html компонента, должен знать о внешней стороне, то есть, используется ли dark bg. Предполагая, что код PHP, который отображает компонент, отделен от кода PHP, который отображает контейнер. Который все еще управляем, но может быть аргументом для шаблона с классом модификатора, как описано выше.

Ноты

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

Дон Кихот
источник

Ответы:

1

Это выглядит как совершенно оправданный дизайн. По сравнению с предложенной вами альтернативой:

  • Существует меньше дублирования кода, чем создание отдельного набора компонентов для белого на черном.
  • Это может сбить с толку и немного запутать, если у вас есть много модификаций для белого на черном.

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


источник