Когда говорим «динамический», подразумеваем JavaScript. Но некоторые динамические функции можно реализовать, используя только CSS. Например, цвета.
С помощью прозрачности
Возможно, вы уже знаете, как создавать цвета с помощью пользовательских свойств CSS и альфа-канала. Освежим память:
:root { --color: 255 255 0; } .selector { background-color: rgb(var(--color) / 0.5); }

Код выше — самый простой для создания пользовательских свойств цвета, но несовершенный. Нужно определить свойство color в цветовом пространстве, которое поддерживает альфа-канал: rgb(), rgba(), hsla().
:root { --color-rgb: 255 255 0; --color-hsl: 5 30% 20%; } .selector { background-color: rgb(var(--color-rgb) / 0.5); background-color: hsl(var(--color-hsl) / 0.5); }

Таким образом, вы не переключать значение цвета пользовательского свойства с одного типа на другой. Обычно про такое пишут в JavaScript, там используется приведение типов. Но вот как это выглядит в CSS:
:root { --color: #fa0000; } .selector { /* Trying to convert a HEX color to an RGB one doesn't work This snippet will not work. this just return a blank white background */ background-color: rgb(var(--color) / 0.5); }

С учётом сказанного, на самом деле невозможно использовать значения цветов HEX для динамических цветов в CSS. Даже указать альфа-канал для цвета HEX, как #FA000060, можно только декларативно, ведь в CSS нет конкатенации:
:root { --color: #fa0000; } .selector { /* You can’t dynamically specify the alpha channel. This will still not do anything */ background-color: var(--color) + "60"; }
Можно объявить значение пользовательского свойства, используя любой цветовой тип: rgb, rgba, hsla, hsl, hex. И уже этот тип с лёгкостью преобразуется в любой другой. Пример управления динамическими цветами:
/* - - - - - - - - - - - - Using hex Colors - - - - - - - - - - - - - - */ :root { --color: #fa0000; } .selector { /* can’t do this */ background-color: rgb(var(--color) / 0.5); /* can do this */ background-color: rgb(from var(--color) r g b / .5); }
Если следовать синтаксису в строке 7, то ничего не получится. Правильный синтаксис в девятой строке показывает, как создавать динамические цвета и управлять ими. ��от как это выглядит, если попытаться использовать именованные цвета:
/* - - - - - - - - - - - - Using Named Colors - - - - - - - - - - - - - - */ :root { --color: red; } .selector { background-color: rgb(from var(--color) r g b / .5); }
С помощью функции calc()
У работы с динамическими цветами через альфа-канал есть свои недостатки: прозрачные цвета не всегда смешиваются с белым, вместо этого сливаются с цветами, на которых расположены. То есть если вам нужна более светлая версия цвета, вы можете изменить альфа-канал, но изменение будет неоднородным. В некоторых местах на странице на новую версию повлияют те цвета, на которых расположены прозрачные. Чтобы ликвидировать это влияние, надо использовать непрозрачные цвета. В CSS можно определить пользовательские свойства и каналы индивидуально:
:root { /* Define individual channels of a specific color */ --color-h: 0; --color-s: 100%; --color-l: 50%; } .selector { /* Dynamically change individual channels */ color: hsl( var(--color-h), calc(var(--color-s) - 10%), var(--color-l) ); }

Но от этого код удлиняется, а значения HEX всё равно не поддерживаются. Решение — функция calc():
:root { --color: #ff0000; } .selector { color: hsl(from var(--color) h calc(s - 10%) l); }
С помощью значения фильтра
Функция filter: brightness(x%) динамически изменяет значения цвета в процентах. Минус метода в том, что функция влияет на конкретный элемент. То есть некоторые части страницы могут отличаться друг от друга.
Не надо залезать в JavaScript, чтобы управлять динамическими цветами на минималках, когда вы делаете тёмный режим или меняете цвет при движении мышки. Пользуйтесь маленькими трюками CSS.
