Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

Огляд custom properties в CSS. Як вони оптимізують код

Усі статті, обговорення, новини про Front-end — в одному місці. Підписуйтеся на телеграм-канал!

Привіт! Мене звати Христина, я Front-end розробниця у компанії Langate Software. Я займаюсь розробкою сайтів і часто стикаюся з проблемою продубльованого коду. І чим масштабніший сайт, тим вищі ризики отримати таку проблему. Часто перевантаженими стають саме CSS-файли, де один і той же стиль застосовується до різних елементів проєкту. А оскільки рядків коду багато, то часто цей факт залишається просто не поміченим і зайвий раз навантажує проєкт.

Саме через цю проблему хочу детальніше розглянути CSS custom properties, які значно допомагають оптимізувати код та уникнути повторюваності.

Що таке custom properties і як їх використовувати

Custom properties, або CSS variables — це властивості (змінні), які визначаються безпосередньо автором CSS-коду, зберігають конкретні значення та можуть повторно використовуватися в документі на різних рівнях.

Оголошення змінної (custom property)

Отже, почнемо з найголовнішого — як правильно оголошувати custom properties для подальшого використання. Варто зазначити, що змінні можна оголошувати як глобально (за допомогою псевдокласу :root) в такому разі властивості будуть доступними по всьому застосунку/ сайту, так і всередині будь-якого селектора — тоді властивості будуть доступними лише для даного селектора та його дочірніх елементів.

Для оголошення змінної використовуються два дефіси «- -», які ставляться перед назвою змінної, її значення та селектор, в рамках якого автор коду хоче застосовувати створену змінну:

Також важливим є те, які регістри будуть використовуватись, коли прописуватиметься назва змінної (всі малі, всі великі, camel case, kebab case, snake case чи pascal case). Якщо я, наприклад, напишу наступні назви змінних: --maincolor, --MAINCOLOR, --mainColor, --main-color, --main_color, --MainColor — це буде 6 різних змінних, яким я зможу присвоїти різні значення, які я зможу використовувати у своєму коді.

Проте потрібно пам’ятати, що така практика не є дуже хорошою з пари причин:

  • потрібно обрати один стиль написання змінних та дотримуватись його;
  • варто присвоювати такі назви змінним, які б логічно їх доповнювали і одразу було зрозуміло, яка змінна відповідає за колір тексту, а яка — за колір фону.

Використання змінної (custom property) в коді

Після того, як була оголошена необхідна змінна, можна її використовувати. Для цього я прописую все як зазвичай — необхідний селектор, назва властивості, а на місці значення властивості прописую потрібну змінну. Для цього я спершу вказую, що це є змінна за допомогою слова var(), а в круглих дужках вписую вже саму назву змінної.

Після такої частини коду для елементу із класом «first» застосовується колір фону, який я вказувала вище для змінної «- -maincolor».

Каскадність і правила наслідування

Custom properties поводяться точно так само, як і звичайні CSS-властивості. Тобто вони підпорядковуються тим самим правилам каскадності та наслідування.

Наприклад, я оголосила змінну «- -background-color» двічі: спочатку для всього <body>, а потім — для тегу <header>, і вона має два різні значення. Якщо я цю змінну захочу використати для елементу з класом «.navbar», буде застосовуватись те значення змінної, яке написане нижче:

І, як результат, ми матимемо елемент «.navbar», забарвлений у темно-синій колір, а не у зелений:

Окрім цього, custom properties «бачать» DOM-дерево. Якщо у вищенаведеному прикладі я створю ще один елемент з класом «.block», але він буде вже поза тегом <header>, йому буде присвоюватись значення змінної, яка була оголошена для тегу <body>:

Це сталось тому, що змінна, яка була оголошена у <header> буде видимою лише для дочірніх елементів цього тега та для нього самого.

Якщо ж змінна «- -background-color» була оголошена лише для тегу <header>, то для елементу з класом «.block» ця змінна буде неіснуючою. В такому разі можна задавати дефолтне («запасне») значення, яке буде застосовуватись у тому разі, якщо змінна буде недоступною. Таке значення записується у var() через кому після назви змінної:

У цьому випадку змінна «--background-color» не «зчитується» і замість неї підставляється запасне значення — #f1545f:

Доступ до custom properties через JS

Завдяки тому, що CSS-змінні є частиною DOM, ми маємо доступ до них через JS. Ми можемо отримувати змінні, їх змінювати або видаляти:

Якщо я створю відповідні кнопки аби отримати, змінити та видалити змінну і пропишу, щоб ці дії виконувались по кліку на них:

то отримаю ось таку невелику візуалізацію взаємодії JS з custom properties:

Коли застосовують такі дії зі змінними? Найпоширенішим кейсом наразі є зміна теми інтерфейсу (найчастіше юзеру пропонують light/dark theme перемикач). При перемиканні кольорової схеми, JS звертається до CSS-змінної та замінює її значення на інше. В такому разі, всі значення в коді, де встановлена ця змінна будуть оновлені.

Також часто дії над custom properties можуть виконуватись тоді, коли потрібно стилістично змінити певний елемент (підсвітка, тінь, зміна фонового кольору), в залежності від backend-відповіді.

Зазвичай, коли мова йде про доступ через JS, більшість уявляє механізм, як JavaScript «передає» значення у CSS. І, справді, найчастіше практикується саме такий підхід. Проте варто зазначити, що зворотній сценарій — також робоча схема. Наприклад, у змінну можна записати не властивість, а логічне твердження, яке буде передаватись у JS:

У даній властивості я створила умову — якщо змінна «х» набуватиме більшого значення, ніж 1, то змінити колір фону для тегу <body> на світло-блакитний (#ddeffd). Тоді у файлі JS я вказую будь-яке значення для змінної «х», яке буде більшим за 1 та отримую змінну «--logic»:

В результаті цього, фон <body> зміниться:

Отже, CSS-змінні можуть взаємодіяти з JS у двосторонньому порядку.

Сумісність з різними браузерами

Наводжу загальну таблицю підтримки браузерами для Desktop та для мобільних пристроїв:

Цифри у прямокутниках вказують на версію браузера, починаючи з якої custom properties стали доступними для користувачів.

Дані для створення таблиці було взято з CSS Variables. За посиланням можна знайти детальнішу інформацію по кожному з браузерів, а також для інших мобільних браузерів.

Крім того, я можу прописати властивості для того випадку, якщо браузером не будуть підтримуватись custom properties. Це можна зробити двома шляхами:

  • У CSS за допомогою правила @supports:

  • Або у JS за допомогою if-else:

Інші плюси та мінуси використання

Одним з ключових плюсів CSS custom properties вважається той факт, що вони мають доступ до DOM дерева. Цю перевагу дуже добре показати на прикладі створення адаптивних стилів (зміна стилів при зміні ширини екрана):

Один рядок коду і всі дочірні компоненти тегу <header>, до яких було застосовано цю змінну — змінять колір з темно-синього на червоний. Тоді як без використання CSS-змінних мені б довелось перераховувати всі ці елементи і для кожного прописувати новий колір.

Одним з головних недоліків є те, що CSS-змінні є нетипізованими, тобто я у значення змінної можу вписати будь-що і воно буде валідним з точки зору зчитування коду. Наприклад, створю зміну з наступним значенням:

З точки зору реалізації, працювати воно не буде. Проте через відсутність типізації devtools мені нічого не напише, як наслідок, — я не зможу провести аналіз та виправити помилку.

Якщо я вже згадала про url(), то тут є ще одне «але» — CSS-змінні не використовують для того, аби вказати шлях до файлу:

В такому разі, мені потрібно у значення змінної записувати шлях разом з url():

Останній недолік, який я б хотіла зазначити, дуже важливий для стилізації, на мою думку, — це недоступність для CSS-змінних плавної анімації. Розглянемо на простому і часто використовуваному прикладі — при натисканні на кнопку бургер меню, виїжджатиме бічна панель, ширина якої, припустимо, буде 300px і до неї додаватиметься клас «.opened». Якщо я вирішу винести це значення у змінну, тому що воно у мене часто зустрічатиметься у проєкті — це логічно. Тоді мій CSS виглядатиме наступним чином (винесла лише необхідні властивості):

За допомогою властивості transition надаю плавності переходу від ширини 0px до 300px, що візуально зробить ефект «виїжджання» моєї бічної панелі. Але це неможливо, оскільки браузер не буде розуміти як розраховувати ці проміжні значення, тому що CSS-змінні, як я згадувала вище, нетипізовані і зчитуються як простий рядок.

Тому матиму результат появи-зникнення бічної панелі без плавної анімації:

Це обмеження використання CSS-змінних є проблемою, тому що зараз анімацію часто використовують, а з custom properties вона буде недоступною.

Висновок

Підсумовуючи, хочу сказати, що CSS custom properties допомагають у написанні DRY (Don’t Repeat Yourself) коду. На мою думку, вони мають хороший потенціал змінити підходи до написання і структуризації CSS.

Проте не варто забувати про можливо тимчасові, але все ж таки обмеження, які вони мають та правильно продумувати логіку свого CSS коду, щоб уникнути проблем у його реалізації.

👍ПодобаєтьсяСподобалось16
До обраногоВ обраному12
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

щиро сподіваюся, що ліди не пропустять в проектах оголошення змінних типу «const var = let» і намагання затягнути логіку в CSS. замість маніпуляцій computed змінними краще керувати виглядом елементів через класи.
в кого є бажання більше дізнатися про CSS variables без води і «цікавих дослідів прикладів» — ось доповідь з минулорічної JS fwdays huijing.github.io/...​ides/101-jsfwdayseu-2022

Підписатись на коментарі