Как сделать динамические цвета в CSS

от автора

Когда говорим «динамический», подразумеваем 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.


ссылка на оригинал статьи https://habr.com/ru/company/netologyru/blog/700302/