Цветовые темы с использованием функций Baseline CSS

Дэвид А. Херрон
David A. Herron

Опубликовано: 11 декабря 2025 г.

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

Вам понадобится основной цвет, а также цвета для действий, состояний при наведении курсора, ошибок и другие элементы пользовательского интерфейса. А как насчет светлого и темного режимов? Внезапно вам понадобится множество цветов, и это может показаться слишком сложным.

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

Создайте базу, используя соответствующие цвета.

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

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

html {
  --base-color: oklch(43.7% 0.075 224);
}

Пользовательское свойство --base-color создается с помощью цветовой функции oklch() . OkLCh — это цилиндрическая форма цветового пространства Oklab, определяющая значения для трех каналов: L (яркость), C (насыщенность), H (оттенок), а также необязательный альфа-канал для управления прозрачностью.

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

Сохраняя те же значения яркости и насыщенности, что и в параметре --base-color , вы можете изменить оттенок на 120 градусов в обоих направлениях, чтобы получить триадическую палитру.

html {
  /* ... */
  --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  --triadic-color-secondary: oklch(from var(--base-color) l c calc(h - 120));
}

Как показано здесь, синтаксис относительного цвета использует цветовую функцию, которая ссылается на исходный цвет ( --base-color в этом примере) с помощью ключевого слова from и корректирует соответствующие каналы цветового пространства на основе выбранного выходного цвета, который в данном случае также будет OkLCh.

В результате вы получите темно-розовый цвет для параметра --accent-color и оттенок золота для параметра --highlight-color , причем оба цвета будут иметь ту же яркость и насыщенность, что и исходный параметр --base-color .

html {
  /* ... */
  --accent-color: var(--triadic-color-primary);
  --highlight-color: var(--triadic-color-secondary);
}

  html {
    /* Input color in the rgb color space*/
    --base-color: teal;

     /* Output color in oklch. Computes to oklch(0.543123 0.0927099 314.769) */
     --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  }

Дополнительный цвет увеличит оттенок на 180 градусов.

html {
  /* ... */
  --complement-color: oklch(from var(--base-color) l c calc(h + 180));
  --border-highlight: var(--complement-color);
}

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

html {
  /* Darken the --base-color by 15% */
  --base-color-darkened: oklch(from var(--base-color) calc(l * 0.85) c h);
  /* Assign this color a meaningful variable name */
  --action-color: var(--base-color-darkened);
  /* Lighten the --action-color by 15% */
  --action-color-light: oklch(from var(--action-color) calc(l * 1.15) c h);
  /* Darken the --action-color by 10% */
  --action-color-dark: oklch(from var(--action-color) calc(l * 0.9) c h);
}

Здесь мы выводим параметр --action-color из параметра --base-color и используем его для кнопок и ссылок. Параметр --action-color имеет два варианта — более светлый и более темный — которые будут применяться даже в том случае, если параметр --action-color будет изменен на относительный цвет, отличный от --base-color .

Вы можете изменять значения каналов, используя математические функции, такие как calc() , или полностью заменяя канал новым значением. Неизмененные каналы обозначаются соответствующими буквами (например, l для неизмененного значения яркости).

Смешивайте цвета с помощью color-mix()

Для других цветовых вариантов можно использовать аналогичный подход и настроить другие каналы пользовательского свойства --base-color . Или же использовать color-mix() для добавления оттенков базового цвета к другим элементам вашего дизайна.

Параметр --border-color представляет собой смесь базового цвета и именованного цвета grey , интерполированного в цветовом пространстве oklab . При использовании в качестве метода цветовой интерполяции это обеспечивает визуально равномерные результаты.

html {
  --base-mix-grey-50: color-mix(in oklab, var(--base-color), grey);
  --border-color: var(--base-mix-grey-50);
}

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

html {
  --background-mix-base-80: color-mix(in oklab,
    var(--background-color) 80%,
    var(--base-color));
  --surface-light: var(--background-mix-base-80);
}

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

[data-input*="text"] {
  --focus-ring: transparent;
  /* ... */
  &:focus {
    --focus-ring: oklch(from var(--border-color) l calc(c + 0.1) h);
  }
}

Включите светлый и темный режимы

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

Поддержка светлой и темной тем оформления с помощью свойства color-scheme

С помощью свойства color-scheme вы можете мгновенно указать браузеру, в каком режиме (светлом, темном или обоих) может отображаться ваш сайт. Это свойство сообщает браузеру, в каких цветовых схемах элемент может отображаться комфортно.

 html {
   color-scheme: light dark;
}

Настройка color-scheme: light dark для псевдоэлемента :root или элемента html :

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

Чтобы пользовательские агенты заранее уведомили вас о поддержке светлого и темного режимов на вашей странице, вы также можете указать на поддержку переключения цветовой схемы, добавив элемент <meta> в раздел <head> документа.

<head>
  <!-- ... -->
   <meta name="color-scheme" content="light dark">
</head>

Задайте «светлый» и «темный» варианты с помощью функции light-dark()

Как автор, вы, возможно, привыкли задавать цвета страницы с помощью @media запроса prefers-color-scheme .

@media (prefers-color-scheme: light) {
  html {
    --background-color: oklch(95.5% 0 162);
    --text-color: black;
  }
}

@media (prefers-color-scheme: dark) {
  html {
    --background-color: oklch(22.635% 0.01351 291.83);
    --text-color: white;
  }
}

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

Изменение цветов страницы с помощью запроса prefers-color-scheme также влечет за собой некоторое дублирование кода, поскольку вам придется определять цвета для каждого режима отдельно.

Если color-scheme задана для всей страницы (или для отдельных элементов), вы можете использовать функцию light-dark() для установки цветов для каждого режима в одной строке кода.

Функция принимает два цвета. Первый используется, когда цветовая схема установлена ​​на «светлый», а второй — когда цветовая схема установлена ​​на «темный».

html {
  color-scheme: light dark;
  /* Color custom property values for both light and dark modes */
  --base-color: light-dark(oklch(43.7% 0.075 224), oklch(89.2% 0.069 224));
  --background-color: light-dark(oklch(95.5% 0 162), oklch(22.635% 0.01351 291.83));
  --accent-color: oklch(from var(--base-color) l c calc(h + 120));
  --active-color: light-dark(var(--action-color-light), var(--action-color-dark));
  /* ... */
}

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

/* custom property usage */
body {
  background-color: var(--background-color);
  /* ... */
}

:any-link {
  /* ... */
  text-decoration-color: var(--accent-color);
}

Предоставьте пользователям возможность управления с помощью встроенного переключателя тем оформления.

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

Если вы создадите переключатель темы, который обновляет атрибут data-scheme элемента <html> , вы сможете использовать тот же атрибут для изменения color-scheme с помощью CSS.

html {
  color-scheme: light dark;

  &[data-scheme="light"] {
    color-scheme: light;
  }

  &[data-scheme="dark"] {
    color-scheme: dark;
  }

  &[data-scheme="green"] {
      --base-color-light: oklch(48.052% 0.11875 151.945);
      --base-color-dark: oklch(92.124% 0.13356 151.558);
      color-scheme: light dark;
   }
}

data-scheme="light" и data-scheme="dark" отображают страницу только в соответствующих цветовых режимах. data-scheme="green" можно просмотреть в любом из этих режимов, а также он изменяет параметр --base-color на оттенок зеленого, что дает совершенно новую палитру, поскольку большинство других цветов основаны на параметре --base-color .

Зарегистрируйте пользовательские свойства с помощью @property

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

Поскольку параметр --base-color используется в качестве базового для многих других цветов в интерфейсе, было бы неплохо убедиться, что он всегда является цветом и имеет резервное значение.

@property --base-color-light {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(43.7% 0.075 224);
}

@property --base-color-dark {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(89.2% 0.069 224);
}

html {
  --base-color: light-dark(var(--base-color-light), var(--base-color-dark));
}

Таким образом, если параметр --base-color будет случайно изменен на недопустимое значение, он всегда будет возвращаться к своему initial-value установленному с помощью правила @property .

Регистрация определенных свойств таким способом также позволяет плавно анимировать цвета в linear-gradient() .

.main-heading {
  background: linear-gradient(in oklch 90deg, var(--text-color) 50%, oklch(from var(--base-color) l c var(--header-hue)));
  background-clip: text;
  color: transparent;
  animation: header-hue-switch 5s ease-in-out infinite alternate;
}

.main-heading имеет фон linear-gradient() , который отображается сквозь прозрачный текст с помощью свойства ` background-clip .

Часть текста демонстрирует hue , который, используя синтаксис относительного цвета, анимируется от значения канала 26.67 до 277 :

@keyframes header-hue-switch {
  from {
    --header-hue: 26.67;
  }

  to {
    --header-hue: 277;
  }
}

При наличии зарегистрированного пользовательского свойства --header-hue эта анимация может происходить плавно, поскольку браузер знает, что это числовое значение.

@property --header-hue {
  syntax: '<number>';
  inherits: false;
  initial-value: 100;
}

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

Заворачивать

Новые инструменты «Базовая линия» помогут вам быстро создать настраиваемую цветовую палитру и сделают процесс создания цветовых переменных более эффективным. Однако вам все равно придется самостоятельно разбираться в бесконечных вариантах и ​​комбинациях цветов.

Создание палитры динамическим способом обеспечивает гибкость. Если вам нужно изменить базовый цвет для брендинга, вы можете просто обновить параметр --base-color , и остальная часть темы будет автоматически изменяться. Или, если вы добавите возможность воспроизведения музыки, вы можете решить динамически изменять базовый цвет в соответствии с воспроизводимой в данный момент песней.

Кредиты

Логика переключения тем адаптирована из компонента переключения тем Адама Аргила.