Как Tailwind сканирует классы

Почему итоговый CSS такой маленький и какая ловушка ждёт с динамическими классами.

Tailwind сканирует ваши файлы, находит все строки классов и кладёт в итоговый CSS только их — неиспользуемые утилиты в сборку не попадают.

Зачем сканирование

Полный набор утилит Tailwind — это мегабайты CSS: тысячи цветов, отступов, размеров. Тянуть всё это в браузер бессмысленно. Поэтому при сборке Tailwind проходит по указанным файлам, выписывает каждое встреченное имя класса и генерирует CSS только для них. В результате итоговый файл обычно весит всего несколько килобайт.

Автоматическое сканирование (Tailwind v4)

Tailwind v4 (актуальная версия). Раньше — в v3 — пути к файлам нужно было вручную перечислять в поле content внутри tailwind.config.js. В v4 это поле больше не нужно: Tailwind сам обнаруживает исходные файлы проекта (эвристика автоматически пропускает .gitignore, бинарные файлы и т.п.). Достаточно одной строки во входном CSS:

@import "tailwindcss";

То есть типичной для v3 ошибки «забыл добавить файл в content — и стили не появились» в v4 попросту нет. Если же нужно явно добавить путь, которого автообнаружение не нашло (например, классы из стороннего пакета), это делают директивой @source в CSS:

@import "tailwindcss";
@source "../node_modules/@my/ui-kit/dist";

Главная ловушка: классы должны быть целыми строками

Сканер ищет буквальные имена классов в коде, а не вычисляет их. Поэтому склеивать класс из кусочков нельзя. Такой код сломается:

<!-- НЕ РАБОТАЕТ: Tailwind не увидит text-red-500 целиком -->
<div class="text-{{ color }}-500">...</div>

Tailwind видит в файле обрывок text- и -500, но не полное имя text-red-500, поэтому нужного CSS не сгенерирует. Правильно — писать полные имена классов и выбирать их целиком:

<!-- РАБОТАЕТ: полные классы -->
<div class="text-red-500">Ошибка</div>
<div class="text-green-500">Успех</div>

В коде на JavaScript то же правило: храните полные имена классов, а не собирайте их конкатенацией.

// Сопоставление статусу — ПОЛНЫЕ имена классов
const styles = {
  error: "text-red-500",
  success: "text-green-500"
};
console.log(styles["success"]);

Вывод:

text-green-500

Итог

  • Tailwind кладёт в сборку только классы, реально встреченные в исходных файлах проекта.
  • В v4 файлы обнаруживаются автоматически — поле content не нужно; при необходимости путь добавляют директивой @source.
  • Имена классов должны присутствовать в коде целиком; склеивать их из переменных нельзя.
Проверьте себя
1. Откуда Tailwind узнаёт, какие классы попадут в итоговый CSS?
AИз package.json
BИз браузера во время выполнения
CИз CDN
DОн автоматически сканирует исходные файлы проекта (в v3 пути задавали в поле content)
2. Почему класс class="text-{{ color }}-500" не сработает?
AСканер ищет буквальные имена классов и не видит text-red-500 целиком
BTailwind не поддерживает красный цвет
CНужно добавить !important
DДвойные фигурные скобки запрещены в HTML
3. Что чаще всего приводит к тому, что классы Tailwind не применяются?
AНет интернета
BИмя класса склеено из переменной, поэтому сканер не видит его целиком
CСлишком новая версия браузера
DОтсутствие jQuery