Как соединить несколько тем на одной странице с помощью CSS?

  • CSS
  • 210
  • 0
  • 0
  • 0
  • 11 дней назад

Уже давно я задумывался о возможности индивидуально формировать отдельные блоки, такие как футер или сайд-бар, не сталкиваясь с проблемами контекстного стиля. Другими словами, «Если эта кнопка используется на темном фоне, при наведении она должна менять цвета. И как мне это сделать?». Представляю вашему вниманию статью о том, как же все-таки совладать с контекстным стилем.

Итак, на днях я немного поэкспериментировал с настраиваемыми свойствами для пользовательского интерфейса Atom. Оказывается, произвольно настраиваемые свойства могут облегчить работу с контекстным стилем (настройка стилей через html). Далее, давайте перейдем к более простому примеру: у нас есть страница, основная часть которой - светлая, но заголовок и футер - темные. Выглядит это так:

3ef0763659afd45bedaf63d53f7d.png

Раньше я бы, вероятно, создал такие вариации, как button--dark или изменил его в header.button {...} . Зависит от самого проекта. Но вот еще один подход: создайте тему с набором переменных, затем примените эту тему к нескольким блокам.

1. Тема по умолчанию

Сначала давайте определимcя с темой по умолчанию и рядом переменных.

[data-theme="default"] {
    --fg: hsl(0,0%,25%);
    --border: hsl(0,0%,75%);
    --bg: hsl(0,0%,95%);
    --button-bg: hsl(0,0%,99%);
    --input-bg: hsl(0,0%,90%);
}

Затем мы создаем компоненты и используем указанные выше переменные.

[data-theme] {
  color: var(--fg);
  background-color: var(--bg);
}
    
.button {
  color: var(--fg);
  border: 1px solid var(--border);
  background-color: var(--button-bg);
}
    
.input {
  color: var(--fg);
  border: 1px solid var(--border);
  background-color: var(--input-bg);
}

И, наконец, добавляем атрибут [data-theme="default"] к телу сайта (body).

<body data-theme="default">

Вы спросите, почему необходимо использовать именно data-theme? Ну, нет конкретной причины. Возможно, подразумевается то, что для каждого элемента следует использовать отдельную тему.

И тогда мы получаем следующее:

dc0a4d290efbbf97930bbab9f9c9.png

2. Тёмная тема

Но наш дизайнер хочет, чтобы заголовок и футер были темными. Хорошо, давайте сформируем еще одну тему. 

[data-theme="dark"] {
  --fg:         hsl(0,10%,70%);
  --border:     hsl(0,10%,10%);
  
  --bg:         hsl(0,0%,20%);
  --button-bg:  hsl(0,0%,25%);
  --input-bg:   hsl(0,0%,15%);
}

Добавим ее в хэдер и футер.

<header data-theme="dark">
<footer data-theme="dark">

И тогда получаем:

3867553400c38fa45ce505874987.png

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

3. Тема заголовка

Спустя несколько месяцев наш дизайнер возвращается с измененным стилем заголовка. «Нужно, чтобы он выглядел посвежее» - побольше цвета.

Нет проблем! И мы меняем тему «заголовка» точно также, как до этого.

[data-theme="hero"] {
  --fg:         hsl(240,50%,90%);
  --border:     hsl(240,50%,10%);
  
  --bg:         hsl(240,33%,30%);
  --button-bg:  hsl(240,33%,40%);
  --input-bg:   hsl(240,33%,20%);
}
<header data-theme="hero">

И вот этот новый заголовок:

3207d1e05ef6681443f278294593.png

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

4. Плюсы

Использование этих тематических «блоков» позволяет вашим компонентам оставаться не привязанными к контексту, и вы сможете использовать их в нескольких темах. Даже на одной странице.

  • Разработчики могут добавлять компоненты, перемещать их, вне зависимости к какому контексту они привязаны. Метка для компонентов остается неизменной.
  • Системные администраторы могут создавать новые компоненты, не беспокоясь о том, где они используются, переменные остаются неизменными.
  • Дизайнеры могут определять новые стили блоков или изменять существующие, без необходимости вносить изменения в HTML или CSS компоненты, они остаются прежними.

5. О чем стоит переживать?

Да-да. Главный вопрос: каковы масштабы этого подхода? Можно ли его использовать и в других случаях?

Итак, я уверен, что он не подходит для всех ситуаций. Найти единое решение для всех-невозможно. И я не могу сказать точно, насколько он масштабируется. Я могу лишь предположить, что он отлично работает с простыми демоверсиями, но я все же хочу найти более крупный проект, чтобы узнать наверняка. Поэтому, если вы использовали (или планируете использовать) этот подход, мне любопытно узнать, как все прошло.

Единственное, о чем стоит переживать, на мой взгляд, это то, что список переменных может быстро расти, если характеристики тем и стилей отличаются между собой. Что-то немного темнее, что-то светлее. Тогда возможнопотребуется определить приоритетные цвета их пределы для каждого компонента (или группы компонентов) и в дальнейшем не использовать общие --fg и --border . Именование переменных, вероятно, наиболее сложная часть.

P.S. Кстати говоря, мне еще очень нравятся CSS цвета уровня 4. Функция color - mod() позволяет вам с помощью настраиваемых произвольных свойств, применять действия darken / lighten (затемнение/осветление) .

[data-theme="dark"] {
    --button-bg: color-mod(var(--bg) lightness(10%));
}

Это позволит менять темы в динамике с меньшим количеством значений с жесткой кодировкой. Просто измените --bg и все остальное приспосабливается соответственно.