Зачем нужны кастомные свойства?
Это обзорная статья по моему недавнему докладу на 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/.