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».