Значения адресов
Не все ресурсы могут располагаться на веб-странице непосредственно и некоторые из них приходится загружать из Интернета. В этом случае можно хранить адрес ссылки в переменной CSS.
:root {
--main-bg: url("https://example.com/cool-image.jpg");
}
.section {
background: var(--main-bg);
}
Вы, наверное, спросите, можно ли интерполировать переменные CSS с помощью функции url()? Рассмотрим следующий пример:
:root {
--main-bg: "https://example.com/cool-image.jpg";
}
.section {
background: url(var(--main-bg));
}
Нет, это невозможно, так как var(--main-bg) воспринимается как сам url(), что приводит к некорректному результату. К тому моменту, когда браузер вычислит значение, оно станет некорректным и не будет работать, как от него ожидалось.
Хранение нескольких значений
Также может оказаться полезным хранение нескольких значений отдельно от значения переменной. Если они корректны, то всё должно работать. Рассмотрим следующий пример:
:root {
--main-color: 35, 90, 209;
}
.section-title {
color: rgba(var(--main-color), 0.75);
}
В данном примере у нас есть функция rgba(), а компоненты RGB хранятся в переменной CSS, разделенной запятыми. Это позволяет гибко менять цвет в ситуациях, когда вы хотите настроить альфа-значение в зависимости от элемента.
Единственным недостатком этого метода является то, что невозможно настроить значение функции rgba() с помощью палитры цветов Инструментов разработчика. Если это важно для вашего проекта, то описанный выше способ использования rgba(), скорее всего, вам не подойдёт.
Вот другой пример, где используется свойство background.
:root {
--bg: linear-gradient(#000, #000) center/50px;
}
.section {
background: var(--bg);
}
.section--unique {
background: var(--bg) no-repeat;
}
Здесь у нас есть два раздела, и в одном из них требуется, чтобы фон не повторялся по горизонтали и вертикали.
Анимация переменных внутри правила @keyframes
Если вы читали спецификацию о переменных CSS, то могли встретить термин animation-tainted (испорченная анимация). Суть его в том, что при использовании переменной CSS внутри правила @keyframes переменная не может быть анимирована.
<div class="box"></div>
.box {
width: 50px;
height: 50px;
background: #222;
--offset: 0;
transform: translateX(var(--offset));
animation: moveBox 1s infinite alternate;
}
@keyframes moveBox {
0% {
--offset: 0;
}
50% {
--offset: 50px;
}
100% {
--offset: 100px;
}
}
Эта анимация не будет работать плавно и двигает блок только для указанных значений (0, 50px, 100px). Согласно спецификации CSS:
...любое пользовательское свойство, используемое в правиле @keyframes, становится animation-tainted, что влияет на его обработку при обращении к нему через функцию var() в свойстве анимации.
Если мы хотим, чтобы описанная выше анимация работала, нам следует действовать по старинке. Это значит, что следует заменить переменную на реальное стилевое свойство, которое мы желаем анимировать.
@keyframes moveBox {
0% {
transform: translateX(0);
}
50% {
transform: translateX(50px);
}
100% {
transform: translateX(100px);
}
}
Дэнни Винтер указал на возможность анимировать переменные CSS внутри @keyframes, регистрируя их с помощью @property. На данный момент это поддерживается только в браузерах на базе Chromium.
@property --offset {
syntax: "<length-percentage>";
inherits: true;
initial-value: 0px;
}
Вычисления
Возможно, вы не знали, но с помощью переменных CSS можно делать вычисления. Рассмотрим следующий пример с аватарами, который я объяснял ранее.
.c-avatar {
display: inline-block;
width: calc(var(--size, 1) * 30px);
height: calc(var(--size, 1) * 30px);
}
У нас могут быть разные варианты аватара. Я установил значение по умолчанию равным 1, поэтому размер в пикселях составляет 30px * 30px. Обратите внимание на отличия в именах классов и на то, как изменение значения переменной --size приводит и к изменению размера аватара.
.c-avatar--small {
--size: 2;
}
.c-avatar--medium {
--size: 3;
}
.c-avatar--large {
--size: 4;
}