Урок 19. Старый vs Новый: hsl-числа против OKLCH

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

⚡ Кратко

Раньше токены хранились как HSL-числа и собирались в конфиге через hsl(var(--primary)). Теперь это готовые цвета OKLCH, связанные с утилитами прямо в CSS.

Определение токена

❌ v3: числа без функции цвета

:root {
  --primary: 222.2 47.4% 11.2%;          /* только числа! */
  --primary-foreground: 210 40% 98%;
}
// tailwind.config.js — оборачивание в hsl()
theme: {
  extend: {
    colors: {
      primary: {
        DEFAULT: "hsl(var(--primary))",
        foreground: "hsl(var(--primary-foreground))",
      },
    },
  },
}

Значение переменной нельзя было использовать напрямую в CSS — только через обёртку. Легко было забыть hsl() и получить «цвет не применяется».

✅ v4: полноценные цвета

:root {
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
}
@theme inline {
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
}

Переменная содержит настоящий цвет: её можно подставить куда угодно — в style, в градиент, в SVG, в свой CSS.

Сводка изменений

Чтоv3v4
Формат значениячисла для hsl()готовый oklch()
Где связь с утилитамиtailwind.config.js@theme inline
Тёмная темаdarkMode: ["class"]@custom-variant dark
Прозрачностьbg-primary/10 работала через хак с <alpha-value>работает штатно
Радиусызначения в конфигеcalc() от --radius
Практическое следствие: если вы копируете тему из статьи и видите строки вида --primary: 222.2 47.4% 11.2%; — это тема для v3. В проекте на v4 она даст невалидные цвета: браузер не поймёт три числа без функции.

Перенос старой темы

  1. Взять значения HSL и перевести в OKLCH (или временно оставить hsl(…) целиком в переменной — так тоже работает).
  2. Удалить блок theme.extend.colors из конфига.
  3. Добавить @theme inline с сопоставлением токенов.
  4. Проверить контраст: OKLCH меняет восприятие светлоты, значения могут выглядеть иначе.
/* переходный вариант: цвет целиком в переменной */
:root { --primary: hsl(222.2 47.4% 11.2%); }