CSS переменные (custom properties): практическое руководство для начинающих
Запрос «CSS переменные» стабильно набирает популярность: всё больше разработчиков переходят от жёстко прописанных значений к гибким и масштабируемым стилям. В этом руководстве мы разложим по полочкам, как работать с custom properties, зачем нужны var() и :root, как быстро включить тёмную тему и управлять цветами из JavaScript.
Быстрый старт: объявление и использование
CSS переменные задаются через имя, начинающееся с двойного дефиса, а читаются функцией var().
:root {
--brand: #6c5ce7;
--gap: 1rem;
}
.btn {
background: var(--brand);
padding: calc(var(--gap) * 1.5) var(--gap);
border-radius: 8px;
color: #fff;
}
:root — это корневой селектор документа (обычно html). Значения, объявленные здесь, доступны везде, если их не переопределить ниже по дереву.
Область видимости и переопределение
CSS переменные наследуются. Это удобно для локальной настройки компонентов без пересборки всего дизайна.
.card {
--card-bg: #ffffff;
--card-text: #111;
background: var(--card-bg);
color: var(--card-text);
padding: 1rem;
}
.card.is-dark {
--card-bg: #1e1f25;
--card-text: #f0f3f7;
}
Переключая модификатор .is-dark, мы меняем только переменные внутри карточки — остальные элементы страницы не затрагиваются.
Тёмная тема за 2 шага
Сделаем базовую тему и переопределим переменные для тёмного режима с помощью атрибута или системных настроек.
:root {
--bg: #ffffff;
--fg: #111111;
--accent: #2f80ed;
}
[data-theme="dark"] {
--bg: #0f1218;
--fg: #e7eaf0;
--accent: #6ab0ff;
}
body {
background: var(--bg);
color: var(--fg);
}
/* Автоподстройка под систему */
@media (prefers-color-scheme: dark) {
:root { --bg: #0f1218; --fg: #e7eaf0; }
}
Чтобы переключать темы из JS, достаточно менять атрибут на <html>: document.documentElement.dataset.theme = 'dark';
var() с запасным значением и типичные ошибки
Если переменная не определена, используйте второй аргумент var() как фолбэк.
.link {
color: var(--link, #0066cc);
}
- Ошибка: забыть единицы измерения внутри переменной. Правильно:
--space: 16px;(а не16). - Ошибка: рассчитывать в
calc()несопоставимые единицы (например,px+emбез нормализации). - Ошибка: ожидать, что переменные будут работать в селекторах или медиа-выражениях — нельзя.
Гибкие размеры: clamp(), min(), max() + переменные
Переменные отлично сочетаются с функциями для «резиновой» типографики и отступов.
:root {
--fs-base: clamp(1rem, calc(0.95rem + 0.5vw), 1.25rem);
--container: min(100% - 2rem, 72rem);
}
body { font-size: var(--fs-base); }
.wrapper { width: var(--container); margin-inline: auto; }
Важно: CSS переменные нельзя подставлять в условиях @media (например, @media (max-width: var(--bp)) не сработает). Используйте их внутри свойств, но не в селекторах и не в медиа-выражениях.
JavaScript + CSS переменные: динамические темы и параметры
Менять значение можно прямо из JS — без пересборки стилей.
// Установить значение
document.documentElement.style.setProperty('--brand', '#ff4757');
// Прочитать текущее значение
const brand = getComputedStyle(document.documentElement)
.getPropertyValue('--brand').trim();
console.log(brand);
// Переключение темы
const root = document.documentElement;
root.dataset.theme = root.dataset.theme === 'dark' ? 'light' : 'dark';
Такой подход особенно удобен для пользовательских настроек (размер шрифта, контраст, акценты) и визуализации данных (например, динамическая окраска графиков).
Анимации и плавные переходы с @property
Чтобы анимировать значения переменных и получать корректные переходы, зарегистрируйте их тип через @property.
@property --brand-hue {
syntax: '<number>';
inherits: false;
initial-value: 260;
}
:root { --brand-hue: 260; }
.btn {
/* hsl() на основе hue-переменной */
background: hsl(var(--brand-hue) 80% 60%);
transition: --brand-hue 300ms ease;
}
.btn:hover { --brand-hue: 330; }
Без @property браузер не знает, как интерполировать значение, и переход может происходить рывком или не происходить вовсе.
Стратегии именования и структура дизайна
- Базовые токены:
--color-fg,--color-bg,--space-1,--radius-2— задаются в:root. - Семантические токены:
--btn-bg,--card-shadow,--link-color— можно переопределять в темах или состояниях. - Локальные токены компонента: объявляйте прямо в корневом селекторе компонента (
.card,.modal).
Проверенный шаблон подключения токенов
:root {
/* Базовые (глобальные) */
--color-fg: #111;
--color-bg: #fff;
--color-accent: #2f80ed;
--space-1: .5rem;
--space-2: 1rem;
--radius-2: 8px;
}
/* Светлая/тёмная темы */
[data-theme="dark"] {
--color-fg: #e7eaf0;
--color-bg: #0f1218;
--color-accent: #6ab0ff;
}
/* Компонент */
.card {
--card-bg: var(--color-bg);
--card-fg: var(--color-fg);
background: var(--card-bg);
color: var(--card-fg);
padding: var(--space-2);
border-radius: var(--radius-2);
box-shadow: 0 6px 18px rgb(0 0 0 / 8%);
}
.card--accent { border: 2px solid var(--color-accent); }
Производительность и поддержка
CSS переменные поддерживаются всеми современными браузерами. Они вычисляются на этапе компоновки, что позволяет экономить на дублировании CSS и упрощает масштабирование. Старайтесь не переопределять слишком много переменных на глубоко вложенных узлах без необходимости — это усложняет дебаг.
Чек-лист лучших практик
- Храните базовые токены в
:root, а локальные — в компонентах. - Используйте семантические имена (не
--blue, а--color-accent). - Добавляйте фолбэки в
var(), особенно для критичных свойств. - Типизируйте анимируемые переменные через
@property. - Не пытайтесь подставлять переменные в селекторах и
@media— используйте их только в значениях свойств.
Что дальше?
Освоив CSS переменные, вы получите более чистую архитектуру стилей, простую темизацию и быстрые правки дизайна. Хотите системно натренировать эти навыки на реальном макете с наставником? Загляните в курс: Прокачать вёрстку на практике и собрать сайт с нуля →
-
Создано 24.11.2025 17:01:40
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.