Як зробити власні властивості (CSS-змінні) більш динамічними
Потужність властивостей властивостей полягає в двох унікальних здібностях:
можливість модифікувати значення з допомогою JS.
Користувацькі властивості стають ще сильнішими зброєю, якщо їх об'єднати з іншими вже існуючими концепціями CSS типу calc().

Практичний курс з верстки адаптивного сайту з нуля!
Вивчіть курс і дізнайтеся, як верстати сучасні сайти на HTML5 та CSS3
За допомогою властивостей користувача можна ефективно робити те, що вміють змінні в препроцесорах типу Sass. Можна встановлювати глобальні та локальні значення змінних і потім використовувати їх у коді. Але завдяки каскадуванню можна задавати нові значення властивостей більш специфічних правилах.
Каскадування може призвести до кількох цікавих підходів, описаних Violet Peña в огляді ключових переваг змінних та Chris в огляді варіантів темизації сайту.
Люди вже кілька років обговорюють ці переваги каскадування, проте найчастіше про них забувають, незважаючи на те, що це ключовий функціонал, який відрізняє їх від препроцесорів. Amelia Bellamy-Royds говорила про це і використала ще у 2014 з SVG, Philip Walton помітив майже всі головні плюси каскадування у 2015, а Gregor Adams показав, як їх можна використовувати у мінімальному фреймворку grid. Ці переваги каскадування – найлегший спосіб почати працювати з властивостями користувача, не забуваючи про прогресивне поліпшення.
ОК. Ми зрозуміли, що властивості користувача дають нам нативний функціонал препроцесорів, а також нові кейси використання завдяки каскадуванню. Але чи є щось у них, чого ми раніше взагалі робити не могли? Звичайно!
Індивідуалізація властивостей
Всі властивості, що складаються з кількох частин,тепер можна використати по-різному. Декілька background можна розділити, а кілька transition-duration можна розбити. Замість transform: translateX(10vmin) rotate(90deg) scale(.8) translateY(5vmin) можна задати одне правило з декількома властивостями користувача, після чого окремо змінювати їх значення.
Знадобиться деякий час на встановлення параметрів, але після вас не потрібно буде змінювати кожну функцію transform вручну під потрібний клас/селектор. Після цього в розмітку можна додавати будь-який або взагалі всі класи для елемента .view, і властивість transform змінюватиметься сама по собі, як показано в демо за кодом зверху.
Незалежні властивості трансформації лише на підході (і першими будуть translaye, scale та rotate), поки що вони працюють із прапором тільки в Chrome. У властивостях користувача цей функціонал вже доступний з більшою підтримкою (також ви зможете задавати порядок функцій. Наприклад, rotate(90deg) translateX(10vmin) відрізняється від translateX(10vmin) rotate(90deg)).
Якщо вас не бентежить, що всі функції ділять одну таймінг опцію, їх можна плавно анімувати за допомогою властивості transition при зміні будь-яких змінних. Майже магія.
Переходимо від значень без одиниць до значень із будь-якими одиницями
Концепції можна розширити, якщо з'єднати їх із calc(). Можна задавати змінні без одиниць виміру (-card-width: 10vmin або -rotation-amount: 1turn) і використовувати їх у більшій кількості місць. Так значення в властивостях користувача стануть ще більш динамічними.
Функції calc() вже кілька років, і, можливо, це найкорисніший інструмент при складанні значень із різними одиницями виміру. Наприклад, якщо у вас є рідка width у відсотках, яку потрібно скоротити на 50px (width: calc(100% - 50px)). Але calc()може набагато більше.
Calc можна використовувати множення для формування значення. Код нижче є повністю валідним і дає нам зрозуміти, що transform і filter пов'язані, тому що в них використовується число 10.
Це не вдалий приклад використання, зазвичай у браузер не надсилають такі обчислення. 10*1vw завжди буде 10vw, тут функція calc марна. Її можна використовувати в препроцесор з циклами, а тут можна обійтися і без calc().
А якщо замінити 10 змінної, що повторюється? Ви зможете задавати безліч значень з однієї точки, навіть якщо значення будуть різними одиницями вимірювання. Ви можете змінити значення в будь-який момент. Завдяки змінним без одиниць вимірювання та calc код нижче повністю валідний:
Можна взяти одне значення (спочатку 10 і пізніше змінюється на 80 або будь-яке інше) і застосувати окремо до vw або vh в трансформаціях. Можна конвертувати в deg для обертання або filter: hue-rotate().

Практичний курс з верстки адаптивного сайту з нуля!
Вивчіть курс і дізнайтеся, як верстати сучасні сайти на HTML5 та CSS3
Одиниці виміру відкидати не обов'язково, але доки вони є в calc, у вас є така можливість. Це відкриває додаткові можливості. Змінюючи базове значення у різних правилах, можна реалізувати анімацію зі зрушеннями в тривалості та затримці. У прикладі нижче ms завжди будуть нашими кінцевими одиницями вимірювання, але результат для нашого delay повинен бути завжди дорівнює половині duration анімації. Для цього нам потрібно буде змінити лише duration-base.
У властивостях можна навіть використовувати кубічні функції Безье. У прикладі нижче створено кілька вертикально розташованих блоків. Кожен трохи менший за попередній, і кожному передано множниккубічної функції Безьє. Цей множник буде окремо застосовуватися до 4 частин базової функції Безьє. Так, у кожного блоку буде своя індивідуальна функція, але між собою функції будуть пов'язані. Додайте або видаліть блок, щоб переглянути, як вони взаємодіють. Клацніть по екрану в будь-якому місці, щоб змінити напрямок анімації.
Для рандомізації базової функції при кожному натисканні використовується JS, через який також задається множник для блоків. Основний CSS:
Якщо ви дивитеся цей приклад у певному браузері (або думаєте, навіщо у прикладі клас .advanced-calc), то ви повинні були запідозрити, що у підході є проблеми. Є дуже важлива проблема… calc не завжди однаково працює у всіх браузерах. Ana Tudor дуже довго обговорювала відмінності у підтримці у браузерах для calc, та написав пару додаткових тестів для інших спрощених кейсів із calc.
Хороша новина: всі браузери, що підтримують властивості користувача, також працюють з calc при конвертації одиниць типу px, vmin, rem та інших лінійних одиниць у властивостях типу width і transform: translate().
Не найкращі новини: у Firefox та Edge часто виникають проблеми з іншими типами одиниць вимірювання типу deg, ms і навіть % в окремих випадках. Тобто попередні filter: hue-rotate() та –rotation ігноруватимуться. У окремих випадках ці браузери навіть розуміють calc(1 * 1), тобто. навіть значення без одиниць виміру (як і rgb()) може стати проблемою.
Всі браузери з підтримкою власних властивостей дозволяють використовувати змінні всередині cubic-bezier, але не всі з них дозволяють використовувати calc на будь-якому рівні. Зараз це основні обмеження з calc, на мій погляд… і вони навіть не пов'язані з властивостями користувача.
З цих проблем у браузерах заведенобаги їх можна обійти за допомогою прогресивного поліпшення. Ранні демо виконують cubic-bezier лише у випадку, якщо знають, що зможуть їх обробити. В іншому випадку ви отримаєте базову функцію. Вони будуть помилково передавати CSS @supports, тому потрібна перевірка типу JS Modernizr:
Властивості користувача - чудовий інструмент CSS, але їхня потужність розкривається в комбінації з JS. У демо з cubic-bezier ми показали, що нове значення властивості можна записати в JS:
Код зверху встановить нове значення для глобальної якості (в CSS встановлено у правилі :root). Або можна піти прямо і задати нове значення для заданого елемента (тим самим дати елементу максимальну специфічність і залишити змінну без змін для інших елементів, що її використовують). Так зручно робити, коли потрібно керувати станом та змінити стилі за заданими значеннями.
David Khourshid обговорив потужні способи взаємодії з властивостями користувача через JS в контексті Observables, і вони дуже добре поєднуються один з одним. Відкрито широкий вибір способів взаємодії користувацьких властивостей та JS, будь-то Observables, зміни станів у React або обробники подій.
Взаємодія особливо важлива властивостей, які набувають кілька значень. У JS вже дуже давно використовується об'єкт style для зміни стилів, але досить складно змінювати якусь окрему частину довгого значення. Якщо потрібно змінити один фоновий малюнок з 10, то нам потрібно знати, який з них ми мінятимемо, а решту залишити недоторканими. З перетворення все ще складніше, коли потрібно змінити тільки rotate(), а scale() залишити без змін. За допомогою JS в властивостях користувача можна змінювати кожну частину значення окремо, що спрощує роботу зі значенням для всієї властивостіtransform.
Тут також добре спрацює спосіб без одиниць виміру. Функція setProperty() може передавати до CSS лише числа, що спростить JS-код у деяких випадках.
Час використовувати?
Властивості користувача доступні в останніх версіях браузерів Mozilla, Google, Opera, Apple і Microsoft. Нині саме час поекспериментувати. Більшість описаного в цій статті вже зараз може використовуватися з добрими фолбеками. Незабаром вийдуть оновлення в браузерах для calc, але властивості користувача вже зараз можна використовувати в окремих ситуаціях. Наприклад, якщо ви працюєте над гібридною мобільною програмою для останніх версій iOS, Android або Windows, у вас буде набагато більше можливостей.
Користувацькі властивості – великий додаток до CSS, і вам знадобиться якийсь час на те, щоб зрозуміти принцип їхньої роботи. Спочатку промочіть ніжки, і якщо сподобалося, пірнайте з головою.
Автор: Dan Wilson
Редакція: Команда webformyself.

Практичний курс з верстки адаптивного сайту з нуля!
Вивчіть курс і дізнайтеся, як верстати сучасні сайти на HTML5 та CSS3