Tailwind CSSMiddleTechnical

Что такое директива @apply и когда её следует использовать?

@apply встраивает утилиты Tailwind в CSS-правила. Используйте для стилизации HTML из CMS/сторонних источников, глобальных базовых стилей и CSS-компонентных библиотек без JSX. В JSX-проектах предпочтительнее выносить стили в компоненты, а не в @apply.

Директива @apply в Tailwind CSS

Директива @apply позволяет встраивать утилитарные классы Tailwind прямо в CSS-правила. Это полезно при создании переиспользуемых стилевых блоков в CSS-файлах без дублирования длинных строк классов в разметке.

Базовый синтаксис

/* globals.css */
.btn-primary {
  @apply inline-flex items-center gap-2 rounded-xl bg-indigo-600 px-5 py-2.5
         text-sm font-semibold text-white shadow-sm
         transition-colors duration-150
         hover:bg-indigo-700
         focus-visible:outline focus-visible:outline-2 focus-visible:outline-indigo-600
         disabled:cursor-not-allowed disabled:opacity-50;
}

.card {
  @apply rounded-xl border border-gray-200 bg-white p-4 shadow-sm;
}
// Использование в компонентах
export function ApplyButton() {
  return <button className="btn-primary">Откликнуться</button>;
}

Когда @apply оправдан

  • Интеграция с библиотеками без JSX — HTML, генерируемый сторонним кодом (CMS, Markdown-рендер, сторонний виджет), нельзя разметить классами Tailwind; @apply позволяет задать стиль через CSS-селектор.
  • Глобальные базовые стили — нормализация тегов h1–h6, a, code в блоке @layer base.
  • Компонентная библиотека без JS-фреймворка — когда нужен только CSS-файл (web components, email-шаблоны).
  • Сложный фокусный/active стиль — правило с несколькими псевдоклассами, которое громоздко писать в className.
/* Глобальные стили типографики через @layer base */
@layer base {
  h1 { @apply text-3xl font-bold tracking-tight text-gray-900; }
  h2 { @apply text-2xl font-semibold text-gray-800; }
  a  { @apply text-indigo-600 underline-offset-2 hover:underline; }
}

/* Стили для HTML из CMS */
@layer components {
  .prose-cms h2  { @apply mt-8 mb-3 text-xl font-bold; }
  .prose-cms p   { @apply mb-4 leading-relaxed text-gray-700; }
  .prose-cms pre { @apply overflow-x-auto rounded-lg bg-gray-900 p-4 text-sm; }
}

Когда @apply не нужен

В React/Vue/Svelte-проектах лучше вынести повторяющиеся классы в компонент, а не в CSS. Компонент — это правильная единица инкапсуляции в мире JSX.

// Предпочтительнее @apply
function Badge({ label }: { label: string }) {
  return (
    <span className="inline-flex items-center rounded-full bg-indigo-100 px-2.5 py-0.5
                     text-xs font-medium text-indigo-800">
      {label}
    </span>
  );
}

Использование с @layer

Всегда помещайте @apply-блоки в соответствующий слой, чтобы корректно управлять специфичностью CSS:

@layer components {
  .input {
    @apply block w-full rounded-md border border-gray-300 bg-white px-3 py-2
           text-sm placeholder-gray-400
           focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500;
  }
}

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

  • Дублирование логики@apply извлекает классы в CSS, но при изменении токенов дизайна вам придётся обновлять и компоненты, и CSS-правила; единый компонент проще поддерживать.
  • Невозможно использовать @apply с вариантами, зависящими от DOM-структурыgroup-hover:, peer-focus: и has-*: нельзя применить через @apply, так как они генерируют CSS-селекторы с требованием наличия класса group/peer на предке/сестре.
  • Специфичность CSS — @apply-блок вне @layer components получает более высокую специфичность, чем обычные утилиты Tailwind, что может неожиданно переопределять классы в разметке.
  • Произвольные значения не работают напрямую@apply w-[320px] работает в v3.2+, но в старых версиях вызывало ошибку; произвольные свойства [property:value] не поддерживаются через @apply.
  • Сложность отладки — в DevTools вы увидите только имя CSS-класса без разворачивания исходных утилит; это усложняет поиск причины конфликта стилей по сравнению с inline-классами.
  • @apply в CSS Modules — при использовании CSS Modules необходимо настроить PostCSS-порядок так, чтобы Tailwind обрабатывался до CSS Modules; неправильная конфигурация приведёт к «Unknown rule @apply».

Common mistakes

  • Смешивать «@apply» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «@apply» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

What the interviewer is testing

  • Объясняет извлечение повторяющихся utility-наборов в CSS без превращения Tailwind в Sass-клон.
  • Показывает на примере, как работает: @apply полезен для маленьких повторов и интеграции с внешней разметкой, но частое применение скрывает композицию и ухудшает локальность стилей.
  • Называет production-нюанс и граничный случай для темы «@apply».

Sources

Related topics