Урок 13. Старый vs Новый: два файла против токенов

📁 Раздел: Состояния и темы ⏱️ Время изучения: ~50 мин 🎯 Сложность: Средняя

⚡ Кратко

Раньше тёмную тему делали вторым 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

Задачаv3v4
Тема по классуdarkMode: 'class' в конфиге@custom-variant dark (…)
Тема по атрибутуdarkMode: ['class', '[data-theme="dark"]']тот же @custom-variant
Токены темыобъект в JS + CSS-переменные вручную@theme inline + переменные
ЦветаRGBOKLCH — ровные ступени в обеих темах