Tailwind CSSMiddleExperience

Расскажите о случае, когда вы улучшали performance, accessibility, testing или maintainability в проекте на Tailwind CSS.

В проекте на Next.js + Tailwind переработал динамическую генерацию классов в явные маппинги, что уменьшило CSS-бандл с 180 до 28 KB. Параллельно улучшил accessibility через focus-visible и внедрил visual regression тесты через Playwright.

Улучшение проекта на Tailwind CSS

Расскажу о реальном опыте улучшения нескольких аспектов проекта на Tailwind CSS — от производительности до тестируемости.

Performance: уменьшение размера CSS-бандла

В большом проекте на Next.js с Tailwind v3 размер CSS в production составлял около 180 KB. Проблема была в динамически генерируемых классах вида bg-${color}-500 — PurgeCSS/content scanner не мог их найти и удалял, поэтому разработчики добавляли всю палитру в safelist.

Решение: переработал генерацию классов, вынес все динамические варианты в явные маппинги объектов:

// До: динамическая генерация (не работает с Tailwind scanner)
const badgeClass = `bg-${status}-500 text-${status}-100`;

// После: явный маппинг
const STATUS_CLASSES: Record<string, string> = {
  success: 'bg-green-500 text-green-100',
  error:   'bg-red-500 text-red-100',
  pending: 'bg-yellow-500 text-yellow-100',
};
const badgeClass = STATUS_CLASSES[status] ?? 'bg-gray-500 text-gray-100';

Убрал safelist, размер CSS упал с 180 KB до 28 KB.

Maintainability: design tokens через CSS-переменные

В Tailwind v4 перешли на @theme-блок в globals.css вместо tailwind.config.js. Это дало единую точку управления цветами, радиусами и отступами без дублирования между JS-конфигом и CSS:

@theme {
  --color-brand-primary: #c28b00;
  --color-brand-dark:    #000000;
  --radius-card: 12px;
  --spacing-section: 64px;
}

Accessibility: контрасты и focus-visible

Аудит показал, что у многих интерактивных элементов не было видимого focus-индикатора — разработчики добавляли outline-none и забывали про focus-visible. Решение: добавил lint-правило и базовый стиль в globals.css:

@layer base {
  :focus-visible {
    @apply outline-2 outline-offset-2 outline-brand-primary;
  }
}

Testing: visual regression через Playwright

Для предотвращения случайных визуальных регрессий подключил Playwright screenshot-тесты для ключевых компонентов. При смене Tailwind-версии или токенов тесты сразу показывают что изменилось визуально.

Подводные камни

  • Динамические классы Tailwind (шаблонные строки) не включаются в production-бандл — только явные полные строки классов проходят через content-scanner.
  • Safelist быстро растёт и теряет контроль — лучше рефакторить динамические классы в маппинги.
  • Tailwind v4 несовместим с конфигурацией v3 (tailwind.config.js) — миграция требует переноса всех кастомных токенов в @theme.
  • outline-none на кнопках ломает keyboard-навигацию — всегда заменяйте на focus-visible:outline-....
  • Большое количество utility-классов в компоненте снижает читаемость — выносите повторяющиеся комбинации в @apply или компоненты.
  • Tailwind JIT генерирует классы на лету — в старых версиях это замедляло cold-start dev-сервера на больших монорепо.
  • Тёмная тема через dark:-вариант требует явного указания strategy в конфиге (class vs media) — по умолчанию media, что не позволяет переключать тему через JS.
  • Переход с v3 на v4 ломает все кастомные плагины, написанные под старое API addUtilities/addComponents.

What hurts your answer

  • Выдумывать опыт или говорить слишком общими фразами
  • Не объяснять свою личную роль в работе с Tailwind CSS
  • Не показывать результат, метрики или извлечённые уроки

What they're listening for

  • Может подготовить честный пример использования Tailwind CSS
  • Показывает свою роль, решения и результат
  • Умеет рефлексировать над trade-offs и уроками

Related topics