Модуль 1 · урок 10 з 14
CSS-змінні й теми
Це прямий критерій приймання: «робочий перемикач теми на чистих CSS-змінних». Ключове слово — чистих: не два файли стилів, не клас на кожному елементі, а один набір токенів, який змінює значення.
Чим CSS-змінна відрізняється від SCSS-змінної
SCSS $var | CSS --var | |
|---|---|---|
| Коли існує | Тільки під час компіляції | У браузері, у рантаймі |
| Чи можна змінити на льоту | Ні | Так — і все перемалюється |
| Каскад і наслідування | Немає | Є: значення успадковується вниз по дереву |
| Для чого | Брейкпоінти, службові числа, логіка міксинів | Токени теми: кольори, відступи, радіуси |
Тема можлива саме тому, що CSS-змінні живуть у рантаймі й каскадують. Змінив значення
на :root — воно змінилось скрізь, де його використали.
Робочий шаблон теми
/* 1. Світла тема — значення за замовчуванням на голому :root */
:root {
--bg: #F4F6FA;
--surface: #FFFFFF;
--ink: #101722;
--accent: #A85A08;
--rule: #D6DEEA;
}
/* 2. Системна темна — але тільки якщо користувач не вибрав світлу вручну */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #0D121A;
--surface: #141B25;
--ink: #E7ECF4;
--accent: #E8A34E;
--rule: #26313F;
}
}
/* 3. Явний вибір користувача — перебиває системний */
:root[data-theme="dark"] {
--bg: #0D121A;
--surface: #141B25;
--ink: #E7ECF4;
--accent: #E8A34E;
--rule: #26313F;
}
body { background: var(--bg); color: var(--ink); }
Логіка трьох блоків важлива, і саме її зазвичай ламають. Стани теми три, а не два:
світла, темна і як у системи. Якщо написати лише медіазапит —
користувач не зможе вибрати вручну. Якщо лише [data-theme] — не спрацює
системна тема на першому візиті.
// перемикач: рівно чотири рядки логіки
const root = document.documentElement;
const saved = localStorage.getItem('theme'); // 'light' | 'dark' | null
if (saved) root.setAttribute('data-theme', saved);
toggle.addEventListener('click', () => {
const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
root.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});
Ніколи не давай кольору єдине оголошення всередині медіазапиту чи
[data-theme] — тоді в іншій темі його просто не буде.
Повний набір токенів завжди лежить на голому :root, а решта блоків
лише перевизначає.
І другий момент: color-scheme: light dark на :root — щоб
скролбари, поля вводу й системні елементи теж перемкнулись.
Токени: як їх називати
Погана назва — --blue. Гарна — --accent. Різниця в тому, що перша
описує колір, а друга — роль. У темній темі акцент буде не синім, і назва
--blue: orange виглядатиме як знущання.
/* ролі, а не кольори */
--bg, --surface, --surface-2 /* фони: сторінка, картка, вкладений блок */
--ink, --ink-2, --ink-3 /* текст: основний, вторинний, приглушений */
--rule, --rule-soft /* лінії */
--accent, --ok, --warn /* акцент і семантика */