Урок 13. Старый vs Новый: два файла против токенов
⚡ Кратко
Раньше тёмную тему делали вторым CSS-файлом или классом на body
с полной копией правил. Теперь — переменными и одним вариантом.
Тема как второй файл
❌ Дублирование правил
/* light.css */
.card { background: #fff; color: #0f172a; border: 1px solid #e2e8f0; }
/* dark.css — копия с другими значениями */
.card { background: #0f172a; color: #f8fafc; border: 1px solid #334155; }
Любое изменение приходится вносить дважды, и рано или поздно файлы расходятся.
✅ Одна разметка, две палитры
/* src/index.css */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@theme inline {
--color-surface: var(--surface);
--color-surface-foreground: var(--surface-foreground);
--color-brand: var(--brand);
}
:root {
--surface: oklch(1 0 0);
--surface-foreground: oklch(0.21 0.01 265);
--brand: oklch(0.55 0.21 264);
}
.dark {
--surface: oklch(0.21 0.01 265);
--surface-foreground: oklch(0.98 0 0);
--brand: oklch(0.62 0.19 264);
}
<div class="rounded-xl border border-border bg-card p-5 text-card-foreground">…</div>
Дублирование через dark: → токены
| Приём | Плюсы | Минусы |
|---|---|---|
dark: у каждого цвета | видно сразу в разметке; не нужна подготовка | классы удваиваются; легко забыть один |
| Семантические токены | разметка короче; тема меняется в одном месте | нужно продумать роли заранее |
Практический совет: начинайте с
dark:, пока компонентов мало. Как только появилась третья
карточка с одинаковыми цветами — заводите токены. Переписывание займёт
полчаса, а сэкономит недели.Что изменилось в v4
| Задача | v3 | v4 |
|---|---|---|
| Тема по классу | darkMode: 'class' в конфиге | @custom-variant dark (…) |
| Тема по атрибуту | darkMode: ['class', '[data-theme="dark"]'] | тот же @custom-variant |
| Токены темы | объект в JS + CSS-переменные вручную | @theme inline + переменные |
| Цвета | RGB | OKLCH — ровные ступени в обеих темах |