Less и пользовательские свойства CSS
Переменные Less существуют только при компиляции: в CSS остаются готовые значения. Пользовательские свойства CSS (--primary) живут в браузере: их можно менять в медиазапросе, для отдельного блока или из JavaScript. Хорошая схема — хранить значения в Less, а в CSS выводить их как пользовательские свойства.
Вывод токенов в :root
Токены — это базовые значения дизайна: цвета, отступы, радиусы. Сохраните их в карту и выведите в :root через each():
// styles/tokens.less
@colors: {
primary: #2563eb;
surface: #ffffff;
text: #111827;
}
:root {
each(@colors, {
--color-@{key}: @value;
});
}Компоненты используют уже пользовательские свойства:
// styles/components/cards.less
.card {
padding: 16px;
color: var(--color-text);
background: var(--color-surface);
border-top: 4px solid var(--color-primary);
}// styles/main.less
@import "tokens";
@import "components/cards";:root {
--color-primary: #2563eb;
--color-surface: #ffffff;
--color-text: #111827;
}
.card {
padding: 16px;
color: var(--color-text);
background: var(--color-surface);
border-top: 4px solid var(--color-primary);
}Тёмная тема
Теперь тема меняется без перекомпиляции: достаточно другого набора значений для атрибута data-theme. Значения для тёмной темы можно вычислить функциями Less:
// styles/themes/dark.less
@primary: #2563eb;
[data-theme="dark"] {
--color-primary: lighten(@primary, 15%);
--color-surface: #1f2937;
--color-text: #f9fafb;
}[data-theme="dark"] {
--color-primary: #6b95f1;
--color-surface: #1f2937;
--color-text: #f9fafb;
}<style>
:root {
--color-primary: #2563eb;
--color-surface: #ffffff;
--color-text: #111827;
}
.card {
padding: 16px;
color: var(--color-text);
background: var(--color-surface);
border-top: 4px solid var(--color-primary);
}
[data-theme="dark"] {
--color-primary: #6b95f1;
--color-surface: #1f2937;
--color-text: #f9fafb;
}
</style>
<div class="card">Светлая карточка</div>
<div data-theme="dark" style="margin-top: 8px">
<div class="card">Тёмная карточка</div>
</div>Подключите файл в main.less строкой @import "themes/dark";. Одна и та же разметка .card выглядит по-разному: внутри data-theme="dark" действуют другие значения свойств.
Кто за что отвечает
| Задача | Less | Пользовательские свойства |
|---|---|---|
| Хранить палитру и размеры | Да | — |
Вычислить оттенок (lighten, fade) | Да | — |
| Сменить тему на странице | — | Да |
| Поменять значение из JavaScript | — | Да |
Точки перелома в @media | Да | — (в условиях медиазапросов не работают) |
Частая ошибка
Функции цвета Less работают при компиляции и не знают, чему будет равно var(--color-primary) в браузере:
// styles/components/buttons.less
.btn:hover {
background: darken(var(--color-primary), 10%);
}Компиляция падает с ошибкой Argument cannot be evaluated to a color. Вычисляйте оттенки из переменной Less (darken(@primary, 10%)) и выводите результат в отдельное свойство, например --color-primary-hover. Если оттенок нужен в браузере, используйте функцию CSS color-mix().