Интересные находки

Значения адресов

Не все ресурсы могут располагаться на веб-странице непосредственно и некоторые из них приходится загружать из Интернета. В этом случае можно хранить адрес ссылки в переменной 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;
}
Автор: Ахмад Шадид
Последнее изменение: 20.02.2024