var()

Функция для использования кастомных свойств в CSS.

Время чтения: 5 мин

Кратко

Скопировано

CSS-функция var() позволяет подставлять кастомные свойства в качестве значения свойств.

Пример

Скопировано

Объявляем кастомное свойство:

        
          
          :root {  --color-cyan: #00ffff;}
          :root {
  --color-cyan: #00ffff;
}

        
        
          
        
      

Используя функцию var() подставляем значение кастомного свойства:

        
          
          .button {  background-color: var(--color-cyan);}
          .button {
  background-color: var(--color-cyan);
}

        
        
          
        
      

Как понять

Скопировано

Функция var() возвращает текущее значение кастомного свойства. Если оно поменяется, то функция var() сразу вернёт актуальное значение.

Механизм работы var()

Передав в функцию var() кастомное свойство, браузер двигается вверх по иерархии элементов в поисках значения кастомного свойства.

Он проверит, установлено ли кастомное свойство на текущем элементе:

  • Если да, подставит вместо var() и остановит поиск.
  • Если нет, переходит на родительский элемент и повторяет проверку.

Браузер будет подниматься вверх по родительским элементам до тех пор пока не найдёт значение. Последней точкой будет проверка наличия значения в :root. Если его нет и там, то функция var() установит значение в initial или резервное значение если он передано.

Определим кастомное свойство:

        
          
          :root {  --card-color: purple;}
          :root {
  --card-color: purple;
}

        
        
          
        
      

Зададим цвет фона карточке, используя функцию var(). Цвет будет фиолетовый:

        
          
          .card {  background-color: var(--card-color);}
          .card {
  background-color: var(--card-color);
}

        
        
          
        
      

Изменим кастомное свойство с помощью .setProperty() в JavaScript:

        
          
          document.documentElement.style.setProperty('--card-color', 'midnightblue')
          document.documentElement.style.setProperty('--card-color', 'midnightblue')

        
        
          
        
      

Теперь там, где установлен цвет фона, функция var() вернёт тёмно-синий цвет.

Открыть демо в новой вкладке

Как пишется

Скопировано

Базовый синтаксис

Скопировано

Функция var() принимает 2 аргумента:

  1. Имя кастомного свойства.
  2. Резервное значение (необязательный).

Если кастомное свойство, на которое ссылается первый аргумент, недопустимо, функция использует второе значение:

        
          
          .card {  padding: var(--card-padding, 10px);}
          .card {
  padding: var(--card-padding, 10px);
}

        
        
          
        
      

Значение padding будет 10px, если --card-padding не определено.

Можно указать несколько резервных значений. Для этого вторым аргументом нужно передать функцию var() с возможными значениями:

        
          
          .title {  font-size: var(--font-size, var(--title-font-size, 20px));}
          .title {
  font-size: var(--font-size, var(--title-font-size, 20px));
}

        
        
          
        
      

Значение font-size будет 20px, если --font-size и --title-font-size не определены.

Резервное значение

Скопировано

Ещё один пример, но немного неочевидный. Если переменная --font-size не определена, то резервное значение будет: --title-font-size, 20px. К сожалению, оно не валидно:

        
          
          .title {  font-size: var(--font-size, --title-font-size, 20px);}
          .title {
  font-size: var(--font-size, --title-font-size, 20px);
}

        
        
          
        
      

Дело в том, что всё, что находится после первой запятой, воспринимается как единое значение. То есть в качестве резервного значения функция вернёт значение от первой запятой до закрывающей скобки.

А такой пример валидный. Резервное значение будет: 10px, 10px:

        
          
          .navigation {  --translate: var(--my-translate, 10px, 10px);  transform: translate(var(--translate));}
          .navigation {
  --translate: var(--my-translate, 10px, 10px);
  transform: translate(var(--translate));
}

        
        
          
        
      
О валидности значений
        
          
          :root {  --text-color: 16px;}.element {  color: var(--text-color);}
          :root {
  --text-color: 16px;
}

.element {
  color: var(--text-color);
}

        
        
          
        
      

В этом примере кастомное свойство --text-color имеет значение 16px, что технически является валидным. Но, когда браузер подставляет значение --text-color вместо var(--text-color), он пытается использовать значение 16px, которое не является допустимым значением для свойства color.

Браузер рассматривает его как недопустимое значение и проверяет, наследуется ли свойство color от родительского элемента. Если да, он его использует. В противном случае устанавливает значение initial.

Возможности

Скопировано

Функцию var() можно подставить как часть значения свойства:

        
          
          .card {  --border-color: black;  border: 1px solid var(--border-color);}
          .card {
  --border-color: black;
  border: 1px solid var(--border-color);
}

        
        
          
        
      

Функция var() также работает с сокращёнными свойствами: margin, padding, border, background, transform, transition и т. д.

Можно использовать для подставки как одного значения:

        
          
          .element {  --margin-top: 10px;  margin: var(--margin-top) 10px 20px 30px;}
          .element {
  --margin-top: 10px;
  margin: var(--margin-top) 10px 20px 30px;
}

        
        
          
        
      

Так и для нескольких:

        
          
          .element {  --margin-top-right: 10px 10px;  margin: var(--margin-top-right) 10px 50px;}
          .element {
  --margin-top-right: 10px 10px;
  margin: var(--margin-top-right) 10px 50px;
}

        
        
          
        
      

Ограничения

Скопировано

Функция var() не может использоваться в качестве имён свойств, селекторов или чего-либо ещё, кроме значений свойств.

Например, следующий код неправильно использует кастомное свойство в качестве имени свойства:

        
          
          .element {  --side: margin-top;  var(--side): 20px;}
          .element {
  --side: margin-top;
  var(--side): 20px;
}

        
        
          
        
      

Вы не можете объединять кастомное свойство и любое другое значение таким образом:

        
          
          .element {  --gap: 20;  margin-top: var(--gap)px;}
          .element {
  --gap: 20;
  margin-top: var(--gap)px;
}

        
        
          
        
      

Вместо этого вы можете использовать такой приём:

        
          
          .element {  --gap: 20;  margin-top: calc(var(--gap) * 1px);}
          .element {
  --gap: 20;
  margin-top: calc(var(--gap) * 1px);
}

        
        
          
        
      

Либо записать полное значение в кастомное свойство:

        
          
          .element {  --gap: 20px;  margin-top: var(--gap);}
          .element {
  --gap: 20px;
  margin-top: var(--gap);
}

        
        
          
        
      

Внутри других функций

Скопировано

Также работает с такими функциями:

calc()

        
          
          .element-1 {  --offset: 50px;  height: calc(100vh - var(--offset));}.element-2 {  --height: 100vh - 50px;  height: calc(var(--height));}
          .element-1 {
  --offset: 50px;
  height: calc(100vh - var(--offset));
}

.element-2 {
  --height: 100vh - 50px;
  height: calc(var(--height));
}

        
        
          
        
      

rgb() и rgba()

        
          
          .element-1 {  --rgb: 0, 0, 0;  color: rgba(var(--rgb), 1);}.element-2 {  --rgb: 0 0 0;  color: rgb(var(--rgb));}.element-3 {  --red: 0;  --green: 0;  --blue: 0;  color: rgb(var(--red), var(--green), var(--blue));}
          .element-1 {
  --rgb: 0, 0, 0;
  color: rgba(var(--rgb), 1);
}

.element-2 {
  --rgb: 0 0 0;
  color: rgb(var(--rgb));
}

.element-3 {
  --red: 0;
  --green: 0;
  --blue: 0;
  color: rgb(var(--red), var(--green), var(--blue));
}

        
        
          
        
      

linear-gradient() и radial-gradient()

        
          
          :root {  --c1: red;  --c2: blue;  --grad: linear-gradient(var(--c1), var(--c2));}.element {  --c1: green;  background: var(--grad);}
          :root {
  --c1: red;
  --c2: blue;
  --grad: linear-gradient(var(--c1), var(--c2));
}

.element {
  --c1: green;
  background: var(--grad);
}

        
        
          
        
      

url()

        
          
          :root {  --url: url("https://example.com/example.jpg");}.element {  background: var(--url);}
          :root {
  --url: url("https://example.com/example.jpg");
}

.element {
  background: var(--url);
}

        
        
          
        
      

Но такой пример работать не будет, так как функция url() воспринимает конструкцию var(--url) как URL:

        
          
          :root {  --url: "https://example.com/example.jpg";}.element {  background: url(var(--url));}
          :root {
  --url: "https://example.com/example.jpg";
}

.element {
  background: url(var(--url));
}