Зачем нужны кастомные свойства?

Виталий Зюзин
3 min readApr 28, 2018

--

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

Есть демо-презентация(корректно отображается на десктопе) и запись доклада.

А в этой статье я вкратце пробегу по рассмотренным в докладе юзкейсам кастомных свойств.

Поехали!

Избегаем дублирования кода

Например, есть код квадратной кнопки:

.button {
width: 100px;
height: 100px;
}

Теперь нужно сделать модификацию кнопки, в которой переопределяются её размеры.

.button--large {
width: 200px;
height: 200px;
}

Если теперь записать размер кнопки в кастомное свойство:

.button {
--size: 100px;
width: var(--size);
height: var(--size);
}

То в модификации достаточно только изменить значение одного свойства --size и больше не дублировать задание width и height:

.button--large {
--size: 200px;
}

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

.button {
box-shadow: 2px 2px 5px 2px red;
transform: rotate(90deg) translate(100px);
}
.button--warn {
box-shadow: 2px 2px 5px 2px blue;
transform: rotate(180deg) translate(100px);
}

В этом случае кастомные свойства позволяют существенно сократить дублирующийся код (заодно зацените, как задавать свойствам значения по умолчанию):

.button {
box-shadow: 2px 2px 5px 2px var(--shadow-color, red);
transform: rotate(var(--rotation-angle, 90deg)) translate(100px);
}
.button--warn {
--shadow-color: blue;
--rotation-angle: 180deg;
}

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

.button {
--shadow-params: 2px 2px 5px 2px;
--shadow-color: red;
/* Так тоже можно */
box-shadow: var(--shadow-params) var(--shadow-color);
}

Устанавливаем зависимость между значениями несвязанных свойств

Можно одновременно менять несколько обычных свойств с помощью одного кастомного.

Возьмём, например, блок с фоновым цветом, заданным с помощью функции hsl и кастомного свойства --number:

.box {
--number: 100;
background-color: hsl(var(--number), 60%, 70%);
}

То же свойство --number можно применять одновременно в значении другого свойства, например, width или letter-spacing. Только нужно привести значение к другой единице измерения с помощью функции calc:

.box {
--number: 100;
width: calc(var(--number) * 1%);
letter-spacing: calc(var(--number) * 0.01em);
}

Теперь меняя значение одного свойства --number можно изменять значения сразу нескольких других свойств.

Изменять это управляющее кастомное свойство можно не только в основном CSS-правиле, но и в любых состояниях блока, в медиа-выражениях и так далее:

.box {
--number: 100;
}
.box:hover {
--number: 50;
}
.box:focus {
--number: 30;
}
@media (min-width: 1000px) {
.box {
--number: 200;
}
}

Используем кастомные свойства в наследовании

Кастомные свойства наследуются всеми потомками того DOM-элемента, которому задаются. Рассмотрим пример:

.box {
--padding: 20px;
padding: var(--padding);
}

Свойство --padding будет наследоваться всеми потомками .box и его можно запросто использовать:

.box__child {
padding: var(--padding);
}

Можно также использовать его у потомков уже дочерних элементов .box__child:

.box__child::after {
--size: calc(100% - var(--padding));
width: var(--size);
height: var(--size);
}

Таким образом, можно «унаследовать» у родителя значение любого свойства, а не только те, которые наследуются по умолчанию (font, color и подобные).

Влияем кастомными свойствами на SVG

Кастомные свойства можно применять не только в контексте HTML, но и для SVG. Возьмём такой код:

<svg>
<path fill="var(--flower-color, #ffb13b)">
<g stroke="var(--stroke-color, #000000)">
</svg>

Теперь, если заинлайнить этот код в HTML, а также если подключить его как <symbol> из встроенного в страницу или внешнего спрайта, на цвет заливки и обводки можно влиять с помощью свойств --flower-color и --stroke-color. Причём, если свойства заданы не будут, применяться значения по умолчанию.

Супер-удобно!

Кастомные свойства и JS

Подробно я уже рассматривал эту тему в статьях «Время переменных» и «JS in CSS».

Кастомные свойства — это удобный мостик, который связывает все части приложения или сайта: JS, CSS, HTML и SVG.

Из JS в CSS можно «пробрасывать» разные штуки:

  • координаты курсора;
  • случайное число;
  • значения разных JS API, математических вычислений;
  • позицию скролла страницы;
  • значения HTML-инпутов на странице.

Также можно хранить в CSS какие-то данные для JS.

Если посмотреть на то, что получилось в целом, то проявляется следующая аналогия:

  • HTML — скелет cайта, HTML-инпуты — сенсорные органы;
  • CSS —внешний вид;
  • JS — мозг, хранит данные и управляет логикой сайта или приложения;
  • кастомные свойства — мышцы, которые всё это связывают воедино.

Ссылка на черновик спецификации кастомных свойств — https://www.w3.org/TR/css-variables/.

--

--