Использование относительных цветов
Модуль CSS цветов определяет синтаксис относительных цветов, который позволяет определять значение CSS <color> относительно другого цвета. Это мощная функция, которая позволяет легко создавать дополнения к существующим цветам — такие как более светлые, темные, насыщенные, полупрозрачные или инвертированные варианты — что способствует более эффективному созданию цветовых палитр.
В этой статье объясняется синтаксис относительных цветов, рассматриваются различные варианты и приводятся примеры.
Общий синтаксис
Относительное значение цвета CSS имеет следующий общий синтаксис:
color-function(from origin-color channel1 channel2 channel3) color-function(from origin-color channel1 channel2 channel3 / alpha) /* color space included in the case of color() functions */ color(from origin-color colorspace channel1 channel2 channel3) color(from origin-color colorspace channel1 channel2 channel3 / alpha)
Относительные цвета создаются с использованием тех же функций цвета, что и абсолютные цвета, но с другими параметрами:
- Включите основную функцию цвета (представленную в примере выше
color-function()), например,rgb(),hsl()и т. д. Выбор функции зависит от цветовой модели, которую вы хотите использовать для создаваемого относительного цвета (цвет результата). - Укажите исходный цвет (представленный выше
origin-color), на основе которого будет создан относительный цвет, перед ключевым словомfrom. Это может быть любое допустимое значение<color>в любой доступной цветовой модели, включая значение цвета, содержащееся в CSS пользовательской переменной, системные цвета,currentColor, или даже другой относительный цвет. - В случае функции
color()укажитеcolorspaceцвета результата. - Укажите выходное значение для каждого отдельного канала. Цвет результата определяется после исходного цвета — представленного выше маркерами
channel1,channel2иchannel3. Канал определяется в зависимости от функции цвета, используемой для относительного цвета. Например, если используетсяhsl(), необходимо определить значения оттенка, насыщенности и светлоты. Каждое значение канала может быть новым, таким же, как исходное, или относительным к значению канала исходного цвета. - Необязательно можно определить значение канала
alphaдля цвета результата, поместив его после слэша (/). Если значение каналаalphaне указано явно, оно по умолчанию принимает значение альфа-каналаorigin-color(а не 100%, как в случае с абсолютными значениями цвета).
Браузер преобразует исходный цвет в синтаксис, совместимый с функцией цвета, а затем деструктурирует его в составляющие цветовые каналы (плюс канал alpha, если у исходного цвета есть альфа-канал). Эти значения доступны в функции под соответствующими именами — r, g, b, и alpha в случае функции rgb(), l, a, b, и alpha в случае функции lab(), h, w, b, и alpha в случае функции hwb(), и т. д. — которые можно использовать для расчета новых значений выходных каналов.
Посмотрим, как работает синтаксис относительных цветов на примере. Следующий CSS используется для стилизации двух элементов <div>, один с абсолютным фоновым цветом — red — и второй с относительным фоновым цветом, созданным с помощью функции rgb() на основе того же значения цвета red.
#one {
background-color: red;
}
#two {
background-color: rgb(from red 200 g b);
}
Вывод выглядит следующим образом:
Относительный цвет использует функцию rgb(), которая принимает red в качестве исходного цвета, преобразует его в эквивалентный цвет rgb() (rgb(255 0 0)) и затем определяет новый цвет с красным каналом со значением 200 и зеленым и синим каналами с теми же значениями, что и исходный цвет (используются значения g и b, доступные внутри функции браузером, оба равны 0).
В результате получается цвет rgb(200 0 0) — немного более темный красный. Если бы мы указали значение красного канала 255 (или просто значение r значение), цвет результата был бы точно таким же, как входное значение. Конечный цвет результата (вычисленное значение) браузера — это значение sRGB color() равносильное rgb(200 0 0) — color(srgb 0.784314 0 0).
Примечание: Как упоминалось выше, при расчете относительного цвета браузер в первую очередь преобразует предоставленный исходный цвет (red в приведенном выше примере) в значение, совместимое с используемой функцией цвета (в данном случае, rgb()). Это делается для того, чтобы браузер смог рассчитать цвет результата на основе исходного цвета. Хотя расчеты выполняются относительно используемой функции цвета, фактическое значение выходного цвета зависит от цветового пространства:
- Старые функции цвета sRGB не могут выразить весь спектр видимых цветов. Цвета результата (
hsl(),hwb()иrgb()) сериализуются вcolor(srgb), чтобы избежать этих ограничений. Это означает, что запрос значения выходного цвета через свойствоHTMLElement.styleили методCSSStyleDeclaration.getPropertyValue()возвращает цвет результата как значениеcolor(srgb ...). - Для более современных функций цвета (
lab(),oklab(),lch(), иoklch()) значения выходных цветов при использовании относительного синтаксиса выражаются в том же формате, что и используемая функция цвета. Например, если используется функция цветаlab(), цвет результата будет значениемlab().
Эти пять строк дают эквивалентный цвет результата:
red rgb(255 0 0) rgb(from red r g b) rgb(from red 255 g b) rgb(from red 255 0 0)
Гибкость синтаксиса
Существует важное различие между значениями деструктурированных каналов исходного цвета, доступными в функции, и значениями каналов цвета результата, заданными разработчиком.
Повторюсь, когда определен относительный цвет, значения каналов исходного цвета доступны в функции для использования при определении значений каналов цвета результата. Следующий пример определяет относительный цвет с использованием функции rgb() и использует значения каналов исходного цвета (доступных как r, g, и b ) для значений каналов результата, что означает, что цвет результата такой же, как исходный цвет:
rgb(from red r g b)
Однако при указании выходных значений вам не обязательно использовать значения каналов исходного цвета. Вам нужно указать значения выходных каналов в правильном порядке (например, красный, затем зеленый, затем синий в случае функции rgb() ), но они могут быть любыми, при условии, что они являются допустимыми значениями для этих каналов. Это обеспечивает высокую степень гибкости относительных цветов CSS.
Например, если вы хотите указать абсолютные значения, как показано ниже, преобразовав red в blue:
rgb(from red 0 0 255) /* output color is equivalent to rgb(0 0 255), full blue */
Примечание: Если вы используете синтаксис относительных цветов, но выводите тот же цвет, что и исходный цвет, или цвет, не основанный на исходном цвете, вы на самом деле не создаете относительный цвет. Вряд ли вы будете делать это в реальном коде, и, скорее всего, вы просто будете использовать абсолютное значение цвета вместо этого. Но мы сочли полезным объяснить, что вы можете это сделать с помощью синтаксиса относительных цветов, как отправную точку для обучения ему.
Вы даже можете смешивать или повторять предоставленные значения. Следующий пример принимает немного более темный красный цвет в качестве входного и выводит светло-серый цвет — каналы r, g, и b цвета результата устанавливаются в значение канала r исходного цвета:
rgb(from rgb(200 0 0) r r r) /* output color is equivalent to rgb(200 200 200), light gray */
Следующий пример использует значения каналов исходного цвета для значений каналов r, g, и b цвета результата, но в обратном порядке:
rgb(from rgb(200 170 0) b g r) /* output color is equivalent to rgb(0 170 200) */
Функции цвета, поддерживающие относительные цвета
В предыдущем разделе мы видели только относительные цвета, определённые с помощью функции rgb(). Однако относительные цвета можно определять с помощью любой современной функции CSS цвета — color(), hsl(), hwb(), lab(), lch(), oklab(), oklch() или rgb(). Общая структура синтаксиса в каждом случае одинакова, хотя исходные значения цвета имеют разные названия, подходящие для используемой функции.
Ниже вы найдёте примеры синтаксиса относительных цветов для каждой функции цвета. Каждый случай — самый простой возможный, с выходными значениями цветовых каналов, точно соответствующими исходным значениям цветовых каналов:
/* color() with and without alpha channel */ color(from red a98-rgb r g b) color(from red a98-rgb r g b / alpha) color(from red xyz-d50 x y z) color(from red xyz-d50 x y z / alpha) /* hsl() with and without alpha channel */ hsl(from red h s l) hsl(from red h s l / alpha) /* hwb() with and without alpha channel */ hwb(from red h w b) hwb(from red h w b / alpha) /* lab() with and without alpha channel */ lab(from red l a b) lab(from red l a b / alpha) /* lch() with and without alpha channel */ lch(from red l c h) lch(from red l c h / alpha) /* oklab() with and without alpha channel */ oklab(from red l a b) oklab(from red l a b / alpha) /* oklch() with and without alpha channel */ oklch(from red l c h) oklch(from red l c h / alpha) /* rgb() with and without alpha channel */ rgb(from red r g b) rgb(from red r g b / alpha)
Стоит ещё раз отметить, что цветовая система исходного цвета не должна совпадать с цветовой системой, используемой для создания выходного цвета. Это обеспечивает большую гибкость. Обычно вас не будут интересовать и вы можете даже не знать систему, в которой определён исходный цвет (у вас может быть просто значение пользовательской свойства для изменения). Вы просто хотите ввести цвет и, например, создать более светлую его версию, поместив его в функцию hsl() и изменив значение светлоты.
Использование пользовательских свойств
При создании относительного цвета можно использовать значения, определённые в пользовательских свойствах CSS, как для исходного цвета, так и в определениях значений выходных цветовых каналов. Давайте рассмотрим пример.
В следующем CSS мы определяем два пользовательских свойства:
-
--base-colorсодержит наш базовый брендовый цвет —purple. Здесь мы используем ключевое слово имени цвета, но относительные цвета могут принимать любой синтаксис цвета для исходного цвета. -
--standard-opacityсодержит стандартное значение непрозрачности бренда, которое мы хотим применить к полупрозрачным блокам —0.75.
Затем мы задаём двум элементам <div> цвет фона. Один получает абсолютный цвет — наш брендовый фиолетовый цвет --base-color. Другой получает относительный цвет, равный нашему брендовому фиолетовому цвету, преобразованному для добавления альфа-канала, равного нашему стандартному значению непрозрачности.
:root {
--base-color: purple;
--standard-opacity: 0.75;
}
#one {
background-color: var(--base-color);
}
#two {
background-color: hwb(from var(--base-color) h w b / var(--standard-opacity));
}
Вывод выглядит следующим образом:
Использование математических функций
Вы можете использовать CSS математические функции, такие как calc(), для вычисления значений выходных цветовых каналов. Давайте рассмотрим пример.
Следующий CSS используется для стилизации трёх элементов <div> с разными цветами фона. Средний элемент получает неизменённый --base-color, а левый и правый элементы получают осветлённые и затемнённые варианты этого --base-color. Эти варианты определяются с помощью относительных цветов — --base-color передаётся в функцию lch(), а выходной цвет изменяет свой канал светлоты для достижения желаемого эффекта с помощью функции calc(). Для осветлённого цвета к каналу светлоты добавляется 20%, а для затемнённого — вычитается 20%.
:root {
--base-color: orange;
}
#one {
background-color: lch(from var(--base-color) calc(l + 20) c h);
}
#two {
background-color: var(--base-color);
}
#three {
background-color: lch(from var(--base-color) calc(l - 20) c h);
}
Вывод выглядит следующим образом:
Значения каналов преобразуются в числовые значения
Чтобы вычисления значений цветовых каналов работали в относительных цветах, все значения исходных цветовых каналов преобразуются в соответствующие <number> значения. Например, в примерах с lch() выше мы вычисляем новые значения светлоты, добавляя или вычитая числа из значения канала светлоты исходного цвета. Если бы мы попытались сделать calc(l + 20%), это привело бы к некорректному цвету — l — это <number> и не может иметь добавленное к нему <percentage>.
- Значения каналов, первоначально указанные как
<percentage>преобразуются в<number>значение, соответствующее функции выходного цвета. - Значения каналов, первоначально указанные как угол
<hue>, преобразуются в число градусов в диапазоне от0до360, включительно.
Проверьте страницы различных функций цвета для получения подробной информации о том, в какие значения преобразуются их исходные значения каналов.
Проверка поддержки браузером
Вы можете проверить, поддерживает ли браузер синтаксис относительных цветов, выполнив его через правило @supports.
Например:
@supports (color: hsl(from white h s l)) {
/* safe to use hsl() relative color syntax */
}
Примеры
Генератор цветовых палитр
В этом примере можно выбрать базовый цвет и тип цветовой палитры. Затем браузер отобразит соответствующую палитру цветов, основанную на выбранном базовом цвете. Доступные варианты цветовых палитр:
-
Дополнительные: включает два цвета, расположенных на противоположных сторонах цветового круга, или, другими словами, противоположные цветовые тона (см. тип данных
<hue>для получения дополнительной информации о тонах и цветовых кругах). Два цвета определяются как базовый цвет и базовый цвет с каналом оттенка +180 градусов. - Трехцветные: включает три цвета, равноудаленные друг от друга вокруг цветового круга. Три цвета определяются как базовый цвет, базовый цвет с каналом оттенка -120 градусов и базовый цвет с каналом оттенка +120 градусов.
- Четырехцветные: включает четыре цвета, равноудаленные друг от друга вокруг цветового круга. Четыре цвета определяются как базовый цвет и базовый цвет с каналами оттенка +90, +180 и +270 градусов.
- Монохромные: включает несколько цветов с одинаковым оттенком, но с различными значениями светлоты. В нашем примере мы определили пять цветов в монохромной палитре — базовый цвет и базовый цвет с каналами светлоты -20, -10, +10 и +20.
HTML
Полный HTML представлен ниже для справки. Наиболее интересные части:
- Пользовательская свойство
--base-colorхранится как встроенноеstyleэлемента<div>с идентификаторомcontainer. Мы поместили его туда, чтобы его значение было легко обновлять с помощью JavaScript. При загрузке примера мы задали начальное значение#ff0000(red) для отображения цветовой палитры, основанной на этом значении. Обратите внимание, что обычно мы бы установили это значение на элементе<html>, но в образце MDN оно удалялось при рендеринге. - Выбор базового цвета создается с помощью элемента управления
<input type="color">. При изменении значения в этом элементе, пользовательское свойство--base-colorустанавливается на это значение с помощью JavaScript, что, в свою очередь, генерирует новую цветовую палитру. Все отображаемые цвета являются относительными цветами, основанными на--base-color. - Набор элементов управления
<input type="radio">позволяет выбрать тип цветовой палитры для генерации. При выборе нового значения JavaScript используется для установки нового класса наcontainer<div>для представления выбранной палитры. В CSS используются селекторы потомков для определения дочерних элементов<div>(например,.comp :nth-child(1)) для применения к ним правильных цветов и скрытия неиспользуемых<div>элементов. - Элемент
container<div>, содержащий дочерние<div>элементы, отображающие цвета сгенерированной палитры. Обратите внимание, что на нём первоначально установлен классcomp, чтобы при первой загрузке страницы отображалась дополнительная цветовая схема.
<div>
<h1>Color palette generator</h1>
<form>
<div id="color-picker">
<label for="color">Select a base color:</label>
<input type="color" id="color" name="color" value="#ff0000" />
</div>
<div>
<fieldset>
<legend>Select a color palette type:</legend>
<div>
<input
type="radio"
id="comp"
name="palette-type"
value="comp"
checked />
<label for="comp">Complementary</label>
</div>
<div>
<input
type="radio"
id="triadic"
name="palette-type"
value="triadic" />
<label for="triadic">Triadic</label>
</div>
<div>
<input
type="radio"
id="tetradic"
name="palette-type"
value="tetradic" />
<label for="tetradic">Tetradic</label>
</div>
<div>
<input
type="radio"
id="monochrome"
name="palette-type"
value="monochrome" />
<label for="monochrome">Monochrome</label>
</div>
</fieldset>
</div>
</form>
<div id="container" class="comp" style="--base-color: #ff0000;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
CSS
Ниже представлен только CSS, устанавливающий цвета палитры. Обратите внимание, как в каждом случае используются селекторы потомков для применения соответствующего background-color к каждому дочернему <div> для выбранной палитры. Для нас более важна позиция <div> в порядке следования кода, а не тип элемента, поэтому мы использовали :nth-child для их выбора.
В последнем правиле мы использовали общий селектор соседства (~) для определения неиспользуемых <div> элементов в каждом типе палитры, устанавливая display: none для предотвращения их рендеринга.
В самих цветах используется --base-color, а также относительные цвета, полученные из этого --base-color. Для относительных цветов используется функция lch() — в неё передаётся исходный --base-color и определяется цвет вывода с соответствующей корректировкой канала светлоты или оттенка.
/* Complementary colors */
/* Base color, and base color with hue channel +180 degrees */
.comp :nth-child(1) {
background-color: var(--base-color);
}
.comp :nth-child(2) {
background-color: lch(from var(--base-color) l c calc(h + 180));
}
/* Use @supports to add in support old syntax that requires deg units
to be specified in hue calculations. This is required for Safari 16.4+. */
@supports (color: lch(from red l c calc(h + 180deg))) {
.comp :nth-child(2) {
background-color: lch(from var(--base-color) l c calc(h + 180deg));
}
}
/* Triadic colors */
/* Base color, base color with hue channel -120 degrees, and base color */
/* with hue channel +120 degrees */
.triadic :nth-child(1) {
background-color: var(--base-color);
}
.triadic :nth-child(2) {
background-color: lch(from var(--base-color) l c calc(h - 120));
}
.triadic :nth-child(3) {
background-color: lch(from var(--base-color) l c calc(h + 120));
}
/* Use @supports to add in support old syntax that requires deg units
to be specified in hue calculations. This is required for Safari 16.4+. */
@supports (color: lch(from red l c calc(h + 120deg))) {
.triadic :nth-child(2) {
background-color: lch(from var(--base-color) l c calc(h - 120deg));
}
.triadic :nth-child(3) {
background-color: lch(from var(--base-color) l c calc(h + 120deg));
}
}
/* Tetradic colors */
/* Base color, and base color with hue channel +90, +180, and +270 degrees */
.tetradic :nth-child(1) {
background-color: var(--base-color);
}
.tetradic :nth-child(2) {
background-color: lch(from var(--base-color) l c calc(h + 90));
}
.tetradic :nth-child(3) {
background-color: lch(from var(--base-color) l c calc(h + 180));
}
.tetradic :nth-child(4) {
background-color: lch(from var(--base-color) l c calc(h + 270));
}
/* Use @supports to add in support old syntax that requires deg units
to be specified in hue calculations. This is required for Safari 16.4+. */
@supports (color: lch(from red l c calc(h + 90deg))) {
.tetradic :nth-child(2) {
background-color: lch(from var(--base-color) l c calc(h + 90deg));
}
.tetradic :nth-child(3) {
background-color: lch(from var(--base-color) l c calc(h + 180deg));
}
.tetradic :nth-child(4) {
background-color: lch(from var(--base-color) l c calc(h + 270deg));
}
}
/* Monochrome colors */
/* Base color, and base color with lightness channel -20, -10, +10, and +20 */
.monochrome :nth-child(1) {
background-color: lch(from var(--base-color) calc(l - 20) c h);
}
.monochrome :nth-child(2) {
background-color: lch(from var(--base-color) calc(l - 10) c h);
}
.monochrome :nth-child(3) {
background-color: var(--base-color);
}
.monochrome :nth-child(4) {
background-color: lch(from var(--base-color) calc(l + 10) c h);
}
.monochrome :nth-child(5) {
background-color: lch(from var(--base-color) calc(l + 20) c h);
}
/* Hide unused swatches for each palette type */
.comp :nth-child(2) ~ div,
.triadic :nth-child(3) ~ div,
.tetradic :nth-child(4) ~ div {
display: none;
}
Примечание по тестированию с помощью @supports
В CSS-примере вы заметите блоки @supports, используемые для предоставления различных значений background-color браузерам, поддерживающим предыдущий черновик спецификации синтаксиса относительных цветов. Они необходимы, потому что начальная реализация Safari основывалась на более ранней версии спецификации, в которой значения исходных каналов цвета разрешались в <number> или другие типы единиц в зависимости от контекста. Это означало, что значения иногда требовали единиц при выполнении сложения и вычитания, что вызывало путаницу. В более новых реализациях значения исходных каналов цвета всегда разрешаются в эквивалентное значение <number>, что означает, что вычисления всегда выполняются с безадресными значениями.
Обратите внимание, как в каждом случае проверка поддержки осуществляется с помощью простого объявления — например, color: lch(from red l c calc(h + 90deg)) — вместо фактического значения, которое нам нужно изменять для других браузеров. При тестировании сложных значений, таких как эти, следует использовать самое простое объявление, которое все ещё содержит синтаксическое различие, которое вы хотите проверить.
Включение пользовательского свойства в проверку @supports не работает — проверка всегда возвращает положительный результат независимо от значения пользовательского свойства. Это происходит потому, что значение пользовательского свойства становится недействительным только тогда, когда оно присваивается как недействительное значение (или часть недействительного значения) обычной CSS-свойства. Для обхода этой проблемы в каждом тесте мы заменили var(--base-color) на ключевое слово red.
JavaScript
В JavaScript мы:
- Добавляем обработчик события
changeдля радиокнопок, чтобы при выборе одной из них выполнялась функцияsetContainer(). Эта функция обновляет значениеclass<div>значением выбранной радиокнопки, чтобы к дочерним<div>элементам для выбранного типа палитры применялись правильные цвета фона. - Добавляем обработчик события
inputдля элемента выбора цвета, чтобы при выборе нового цвета запускалась функцияsetBaseColor(). Эта функция устанавливает значение пользовательского свойства--base-colorна новый цвет.
const form = document.forms[0];
const radios = form.elements["palette-type"];
const colorPicker = form.elements["color"];
const containerElem = document.getElementById("container");
for (const radio of radios) {
radio.addEventListener("change", setContainer);
}
colorPicker.addEventListener("input", setBaseColor);
function setContainer(e) {
const palType = e.target.value;
console.log("radio changed");
containerElem.setAttribute("class", palType);
}
function setBaseColor(e) {
console.log("color changed");
containerElem.style.setProperty("--base-color", e.target.value);
}
Результаты
Вывод показан ниже. Это начинает демонстрировать возможности относительных CSS-цветов — мы определяем несколько цветов и генерируем палитры, которые обновляются в реальном времени при изменении одного пользовательского свойства.
Обновление цветовой схемы пользовательского интерфейса в режиме реального времени
В этом примере показана карточка с заголовком и текстом, но с уловкой — под карточкой расположен ползунок (<input type="range">). При изменении его значения JavaScript используется для установки нового значения ползунка в качестве значения пользовательской --hue свойства.
Это, в свою очередь, изменяет цветовую схему всего пользовательского интерфейса:
- Значение
--base-color— относительный цвет с каналом оттенка, установленным в значение--hue. - Другие цвета, используемые в дизайне, — это относительные цвета, основанные на
--base-color. В результате они изменяются при изменении--base-color.
HTML
Ниже показан HTML для примера.
- Элемент
<main>служит внешней оболочкой для размещения остального содержимого, позволяя расположить карточку и форму по центру как по вертикали, так и по горизонтали внутри<main>в едином блоке. - Элемент
<section>содержит элементы<h1>и<p>, определяющие содержимое карточки. - Элемент
<form>содержит элемент управления (<input type="range">) и его<label>.
<main>
<section>
<h1>A love of colors</h1>
<p>
Colors, the vibrant essence of our surroundings, are truly awe-inspiring.
From the fiery warmth of reds to the calming coolness of blues, they bring
unparalleled richness to our world. Colors stir emotions, ignite
creativity, and shape perceptions, acting as a universal language of
expression. In their brilliance, colors create a visually enchanting
tapestry that invites admiration and sparks joy.
</p>
</section>
<form>
<label for="hue-adjust">Adjust the hue:</label>
<input
type="range"
name="hue-adjust"
id="hue-adjust"
value="240"
min="0"
max="360" />
</form>
</main>
CSS
В CSS у :root установлено значение по умолчанию --hue , а также относительные lch() цвета для определения цветовой схемы, плюс радиальный градиент, заполняющий весь документ.
Относительные цвета определяются следующим образом:
-
--base-color: Основной цвет получает исходный цветred(хотя можно использовать любой полный цвет) и корректирует значение оттенка в соответствии с заданным значением--hueпользовательской свойства. -
--bg-color: Значительно более светлый вариант--base-color, предназначенный для использования в качестве фона. Он создается путем взятия исходного цвета--base-colorи добавления 40 к его значению светлоты. -
--complementary-color: Дополнительный цвет, расположенный на 180 градусов от--base-colorна цветовом круге. Он создается путем взятия исходного цвета--base-colorи добавления 180 к его значению оттенка.
Теперь ознакомьтесь с остальной частью CSS и обратите внимание на все места, где используются эти цвета. Это включает в себя фоны, рамки, text-shadow и даже accent-color ползунка.
Примечание: Для краткости показаны только части CSS, относящиеся к использованию относительных цветов.
:root {
/* Default hue value */
--hue: 240;
/* Relative color definitions */
--base-color: lch(from red l c var(--hue));
--bg-color: lch(from var(--base-color) calc(l + 40) c h);
--complementary-color: lch(from var(--base-color) l c calc(h + 180));
background: radial-gradient(ellipse at center, white 20%, var(--base-color));
}
/* Use @supports to add in support for --complementary-color with old
syntax that requires deg units to be specified in hue calculations.
This is required for in Safari 16.4+. */
@supports (color: lch(from red l c calc(h + 180deg))) {
body {
--complementary-color: lch(from var(--base-color) l c calc(h + 180deg));
}
}
/* Box styling */
section {
background-color: var(--bg-color);
border: 3px solid var(--base-color);
border-radius: 20px;
box-shadow: 10px 10px 30px rgb(0 0 0 / 0.5);
}
h1 {
background-color: var(--base-color);
text-shadow:
1px 1px 1px var(--complementary-color),
-1px -1px 1px var(--complementary-color),
0 0 3px var(--complementary-color);
}
/* Range slider styling */
form {
background-color: var(--bg-color);
border: 3px solid var(--base-color);
}
input {
accent-color: var(--complementary-color);
}
JavaScript
JavaScript добавляет обработчик события input для элемента управления ползунком. При установке нового значения выполняется функция setHue(). Эта функция задает новое значение inline --hue пользовательской свойства для :root (элемента <html>), которое переопределяет исходное значение по умолчанию, заданное в CSS.
const rootElem = document.querySelector(":root");
const slider = document.getElementById("hue-adjust");
slider.addEventListener("input", setHue);
function setHue(e) {
rootElem.style.setProperty("--hue", e.target.value);
}
Результаты
Выходные данные показаны ниже. Здесь используются относительные цвета CSS для управления цветовой схемой всего пользовательского интерфейса, которую можно настраивать в режиме реального времени при изменении одного значения.
См. также
- Тип данных
<color> - Модуль CSS цветов
- sRGB в Википедии
- CIELAB в Википедии
- Синтаксис относительных цветов CSS на developer.chrome.com (2023)
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors