Кастомные свойства (которые также известны как CSS переменные) позволяют нам хранить значения свойств для их последующего переиспользования в наших таблицах стилей. Если вы недавно узнали про них, то можете задаваться вопросом, а чем они лучше обычных переменных препроцессора (если вы конечно используете какой-либо препроцессор). На данный момент я часто использую кастомные свойства в работе и решила собрать здесь несколько вариантов их применения.

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

Цветовые функции

Кастомные свойства не просто содержат полные значения свойств, но и могут использоваться для хранения лишь части этих значений. Обычно в пример приводят способ применения в цветовых функциях CSS.
HSLA особенно хорошо подходит для кастомных свойств, предоставляя нам, как разработчикам, беспрецедентный уровень контроля, когда дело доходит до смешивания цветов.

.some-element {
  background-color: hsla(
    var(--h, 120),
    var(--s, 50),
    var(--l, 50),
    var(--a, 1)
  );
}

.some-element.darker {
  --l: 20;
}

Мы также можем сделать разные крутые штуки, например такие, как вычисление дополнительных цветов. Эту статью я написала в прошлом году и она гораздо более детально описывает возможности по манипулированию цветом с применением кастомных переменных, и у Sara Soueidan есть отличная статья на эту же тему.

Сокращенные свойства

Если вы используете сокращенные свойства, такие как animation, и и вам нужно изменить одно значение для применения этого свойства к другому элементу, то повторная запись всех свойств чревата ошибками и добавляет дополнительную сложность при поддержке. Используя кастомные свойства мы можем очень легко изменять одно значение в сокращенном свойстве:

.some-element {
  animation: var(--animationName, pulse) var(--duration 2000ms) ease-in-out
    infinite;
}

.some-element.faster {
  --duration: 500ms;
}

.some-element.shaking {
  --animationName: shake;
}

Повторяющиеся значения

Предположим, у нас есть элемент, который имеет одно значение для верхнего отступа (padding), но другие, одинаковые значения для всех остальных сторон. Написание подобного свойства может быть слегка утомительным, особенно, если мы хотим изменить значения отступов:

.some-element {
  padding: 150px 20px 20px 20px;
}

@media (min-width: 50em) {
  padding: 150px 60px 60px 60px;
}

Использование кастомных свойств означает, что у нас может быть всего одно место в котором мы можем изменить сразу все значения для этого отступа. Более того, если это стандартное значение, которое используется на своем сайте, мы можем объявить его в качестве переменной в файле конфигурации или в токенах дизайна нашего сайта.

:root {
  --pad: 20px;
}

@media (min-width: 50em) {
  :root {
    --pad: 60px;
  }
}

.some-element {
  padding: 150px var(--pad) var(--pad) var(--pad);
}

Вычисленные значения

Кастомные свойства могут быть очень удобны для хранения вычисленных значений (из функции calc()), которые в свою очередь тоже могут быть вычислены из других пользовательских свойств. Одним из примеров может послужить - расчет дополнительных цветов, как уже упоминалось ранее. Другой пример - когда вы хотите вычислить обратное свойство. Я недавно писала статью, для CSS Tricks про вычисление обратной кривой cubic-bezier с помощью кастомных свойств.

Я довольно часто использую кастомные свойства со свойством clip-path, если мне нужно вычислить один путь относительно другого, или относительно известной переменной. Следующий код, из демонстрации, вычисляет точки clip-path для двух псевдоэлементов, чтобы создать эффект разрезанного пополам элемента.

.element {
  --top: 20%;
  --bottom: 80%;
  --gap: 1rem;
  --offset: calc(var(--gap) / 2);
}

.element::before {
  clip-path: polygon(
    calc(var(--top) + var(--offset)) 0,
    100% 0,
    100% 100%,
    calc(var(--bottom) + var(--offset)) 100%
  );
}

.element::after {
  clip-path: polygon(
    calc(var(--top) - var(--offset)) 0,
    calc(var(--bottom) - var(--offset)) 100%,
    0 100%,
    0 0
  );
}

Последовательные анимации

Если мы хотим сделать анимацию для нескольких дочерних элементов, мы можем сделать это очень просто и изящно, установив animation-delay для каждого элемента , определив кастомное свойство как индекс элемента:

.element {
  --delay: calc(var(--i, 0) * 500ms);
  animation: fadeIn 1000ms var(--delay, 0ms);
}

.element:nth-child(2) {
  --i: 2;
}

.element:nth-child(3) {
  --i: 3;
}

К сожалению на данный момент мы должны назначать переменную явно, что может быть проблемой, если мы не знаем количество элементов которые нужно анимировать. Splitting JS - это отличная JavaScript библиотека которая позаботится об этом, назначив индекс элемента в качестве переменной, и будет очень полезна для такого рода последовательной анимации. Но было бы очень здорово не использовать JS!

Adam Argyle недавно предложил две новые CSS-функции, sibling-count() и sibling-index(), которые сильно изменят правила игры, добавив множество новых возможностей в CSS. На данный момент они далеки от того, чтобы быть внедрены в какой-либо браузер, но это были бы невероятно мощные инструменты, так что нужно следить за их развитием.

Адаптивные гриды

Я уже писала про них в этой статье, но кастомные свойства могут помочь работать с макетами со сложной сеткой. Допустим у нас есть восьми-колоночная сетка, которую нам надо изменить на двенадцати-колоночную сетку при определенном разрешении:

:root {
  --noOfColumns: 8;
}

@media (min-width: 60em) {
  :root {
    --noOfColumns: 12;
  }
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--noOfColumns), 1fr);
}

Нам не нужно записывать полное значение свойства всякий раз, когда мы хотим обновить количество столбцов - мы можем использовать кастомные свойства. Это относительно простой пример, но пользы от такого подхода будет гораздо больше, если у нас будет более сложная сетка. И это способ также может применяться к таким вещам, как размер строк или размещение элементов.

Вендорные префиксы

Некоторые свойства (например, clip-path) все еще требуют префиксы для определенных браузеров - хотя, к счастью, их число уменьшается. Если вам нужно написать префикс для свойства, а затем вы хотите изменить значение этого свойства, вы должны убедиться, что вы изменили его и в свойстве с префиксом. С помощью пользовательских свойств мы могли бы вместо этого написать:

.some-element {
  --clip: polygon(0 0, 100% 0, 50% 100%, 0 100%);

  -webkit-clip-path: var(--clip);
  clip-path: var(--clip);
}

Теперь у нас есть только одно место в коде которое нам понадобится изменить.

Выводы

Это далеко не полный список применения кастомных свойств, но эти семь примеров я регулярно использую для своего рабочего процесса и они помогут вам сделать код более эффективным и поддерживаемым. Нет сомнений в том, что вы откроете для себя множество других применений!