Pièges et alternatives de @apply
Identifiez les utilisations courantes et incorrectes de @apply, comprenez les effets sur la spécificité et évaluez les alternatives d’extraction de composants, comme les composants JSX.
Pièges et alternatives de @apply est une leçon Tailwind CSS Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Tailwind CSS Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Tailwind CSS Academy comprend 4 leçons au total.
Quand @apply pose problème
Bien que @apply semble être un moyen pratique d’organiser les styles, son utilisation excessive entraîne plusieurs problèmes bien documentés. Ceux-ci comprennent la difficulté à comprendre quels utilitaires sont actifs, la perte d’une source unique de vérité pour les styles des composants et des surprises liées à la spécificité. Comprendre ces pièges vous aide à déterminer quand @apply est réellement le bon outil et quand une meilleure solution existe.
Piège 1 : recréer le CSS traditionnel
Le mauvais usage le plus courant de @apply consiste à l’utiliser pour recréer des classes CSS conventionnelles : donner à chaque élément une seule classe sémantique comme .header-title, puis la remplir d’utilitaires. C’est exactement le modèle dont Tailwind a été conçu pour s’éloigner. Vous cumulez les inconvénients des deux approches : des fichiers CSS verbeux ET un HTML qui exige de savoir quelles classes CSS existent. Le résultat est plus difficile à maintenir que l’une ou l’autre approche utilisée seule.
/* ANTI-PATTERN: Recreating traditional CSS with @apply */
.page-header { @apply bg-white border-b px-6 py-4; }
.page-title { @apply text-2xl font-bold text-gray-900; }
.page-meta { @apply text-sm text-gray-500 mt-1; }
.page-action { @apply ml-auto; }
/* BETTER: Just write the utilities directly in HTML -->
<header class="bg-white border-b px-6 py-4">
<h1 class="text-2xl font-bold text-gray-900">Title</h1>
<p class="text-sm text-gray-500 mt-1">Meta</p>
</header>Piège 2 : perdre la visibilité des variantes
Lorsque vous masquez des classes utilitaires dans des règles @apply d’un fichier CSS, elles deviennent invisibles pour l’analyseur JIT, sauf si le fichier CSS figure dans votre tableau content. Plus important encore, les développeurs qui liront votre HTML ultérieurement ne pourront pas voir tous les styles d’un seul coup d’œil : ils devront ouvrir le fichier CSS, trouver la classe et développer mentalement le contenu de @apply. Cela réduit le caractère auto-documenté de l’approche utilitaire de Tailwind.
/* CSS: @apply hides what the component looks like */
.hero-button {
@apply px-8 py-3 bg-indigo-600 text-white rounded-full font-semibold
hover:bg-indigo-500 shadow-lg hover:shadow-indigo-500/50
transition-all duration-200;
}
<!-- HTML: developer sees only the class name, not the styles -->
<button class="hero-button">Get Started</button>
<!-- Better: developer sees everything at a glance -->
<button class="px-8 py-3 bg-indigo-600 text-white rounded-full font-semibold hover:bg-indigo-500 shadow-lg transition-all duration-200">
Get Started
</button>Piège 3 : surprises liées à la spécificité
Lorsque vous utilisez @apply sans placer le résultat dans @layer components, le bloc CSS compilé se trouve à l’emplacement de votre feuille de styles où vous l’avez écrit. Cela peut provoquer des problèmes de spécificité inattendus, la classe de votre composant prenant le dessus sur les utilitaires intégrés, car elle apparaît plus loin dans le fichier. Utilisez toujours @layer components afin que la cascade des couches gère la spécificité de manière prévisible.
/* BAD: No @layer wrapper — could override utilities unexpectedly */
.btn-primary {
@apply bg-blue-600 text-white;
}
/* Later in the same file: */
/* p-4 might not override .btn-primary if placed before it */
/* GOOD: Use @layer components */
@layer components {
.btn-primary {
@apply bg-blue-600 text-white;
}
/* Now utilities always override correctly */
}Piège 4 : impossible d’utiliser @apply avec des valeurs arbitraires
La syntaxe des valeurs arbitraires de Tailwind (notation entre crochets, comme w-[347px] ou bg-[#1a2b3c]) ne fonctionne pas dans @apply. Il s’agit d’une limitation fondamentale : les valeurs arbitraires sont résolues lorsque l’analyseur JIT les trouve dans les fichiers source, tandis que @apply intervient à une autre étape. Si votre composant nécessite des valeurs ponctuelles, vous devez utiliser des propriétés CSS classiques dans la règle plutôt que des utilitaires à valeurs arbitraires.
/* ERROR: Arbitrary values in @apply don't work */
.hero {
@apply w-[347px] bg-[#1a2b3c]; /* Will not compile! */
}
/* CORRECT: Use plain CSS for arbitrary values */
.hero {
@apply rounded-xl shadow-lg; /* Regular utilities work fine */
width: 347px; /* Plain CSS for the arbitrary value */
background-color: #1a2b3c; /* Plain CSS for custom color */
}La véritable alternative : les composants JSX
Dans React et les autres frameworks de composants, la meilleure alternative à @apply est une abstraction de composant. Un composant Button accepte une propriété variant et génère en interne les bonnes classes utilitaires. Les styles sont encapsulés, l’API est typée et les modifications sont répercutées partout où le composant est utilisé. C’est le modèle recommandé par l’équipe Tailwind pour les bases de code composées principalement de composants.
// React component replaces @apply .btn-primary
const variantStyles = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',
outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50',
ghost: 'text-gray-600 hover:bg-gray-100 hover:text-gray-900',
};
export function Button({ variant = 'primary', children, ...props }) {
return (
<button
className={'inline-flex items-center px-4 py-2 rounded-lg text-sm font-medium transition-colors ' + variantStyles[variant]}
{...props}
>
{children}
</button>
);
}La bibliothèque clsx pour les classes conditionnelles
La bibliothèque clsx (ou son alternative classnames) permet de composer proprement des classes conditionnelles en JavaScript. Au lieu de concaténer des chaînes ou d’utiliser des littéraux de modèle, transmettez un objet ou un tableau à clsx : la bibliothèque se charge de les assembler selon les conditions. C’est la manière de référence de gérer les classes de variantes dans les composants React sans @apply.
import clsx from 'clsx';
function Button({ variant, size, fullWidth, children }) {
return (
<button className={clsx(
'inline-flex items-center justify-center rounded-lg font-medium transition-colors',
{
'px-4 py-2 text-sm': size === 'md' || !size,
'px-3 py-1.5 text-xs': size === 'sm',
'px-6 py-3 text-base': size === 'lg',
},
{
'bg-blue-600 text-white hover:bg-blue-700': variant === 'primary',
'border border-gray-300 text-gray-700 hover:bg-gray-50': variant === 'outline',
},
fullWidth && 'w-full',
)}>
{children}
</button>
);
}Les fragments de modèles HTML comme alternative
Dans les projets HTML sans framework (par exemple les applications générées côté serveur avec les modèles Django, Laravel ou Go), l’équivalent d’un composant est un fragment de modèle ou un include. Extrayez le fragment HTML répété avec ses utilitaires dans un fragment, puis incluez-le partout où cela est nécessaire. Vous obtenez ainsi le même avantage en matière de duplication qu’avec @apply, tout en conservant les styles dans le HTML, là où ils doivent se trouver.
<!-- Jinja2 / Django example -->
<!-- templates/components/button.html -->
<button class="inline-flex items-center px-4 py-2 rounded-lg font-medium text-sm bg-blue-600 text-white hover:bg-blue-700 transition-colors" type="{{ type|default:'button' }}">
{{ label }}
</button>
<!-- Used via include -->
{% include 'components/button.html' with label='Save' type='submit' %}Quand @apply est le bon choix
Après avoir compris les pièges, vous pouvez repérer les cas réels où @apply est l’outil approprié. Il s’agit notamment de la mise en forme d’un HTML que vous ne pouvez pas contrôler (Markdown généré, sortie d’un CMS, HTML d’une bibliothèque tierce), de l’harmonisation des éléments de formulaire du navigateur avec le plugin de formulaires et de l’ajout d’utilitaires Tailwind à des éléments SVG ou canvas externes. Dans ces cas, vous ne pouvez pas ajouter de classe à l’élément : @apply est donc la seule option.
@layer components {
/* Styling markdown content rendered by a CMS */
.prose-content h1 { @apply text-4xl font-bold text-gray-900 mb-6 mt-8; }
.prose-content h2 { @apply text-3xl font-semibold text-gray-800 mb-4 mt-6; }
.prose-content p { @apply text-gray-600 leading-relaxed mb-4; }
.prose-content a { @apply text-blue-600 underline underline-offset-2 hover:text-blue-800; }
.prose-content ul { @apply list-disc list-inside space-y-1 mb-4 text-gray-600; }
}Les recommandations officielles de l’équipe Tailwind
L’équipe Tailwind CSS déconseille explicitement d’utiliser @apply pour organiser les styles simplement parce que cela « semble plus propre ». Sa documentation indique : « If you find yourself wanting to use @apply to DRY up your Tailwind CSS, you should probably be using a component. » Les abstractions de composants sont plus explicites, plus faciles à rechercher et plus faciles à maintenir à grande échelle. @apply doit être une solution de dernier recours, et non un premier réflexe.
Refactoriser @apply en composants
Si vous disposez d’un projet existant qui utilise abondamment @apply, vous pouvez migrer progressivement vers des composants. Commencez par la classe de composant la plus utilisée (généralement les boutons ou les cartes), créez un composant adapté, puis remplacez les utilisations fichier par fichier. Chaque remplacement améliore la sécurité offerte par le typage, la proximité des styles et la lisibilité. La migration présente peu de risques, car le rendu visuel devrait être identique : vous ne changez que le mécanisme, pas la conception.
/* BEFORE: @apply in CSS */
@layer components {
.btn-primary { @apply bg-blue-600 text-white px-4 py-2 rounded-lg font-medium; }
}
<!-- BEFORE: HTML -->
<button class="btn-primary">Save</button>
/* AFTER: Component abstraction */
// Button.jsx
export function Button({ children }) {
return <button className="bg-blue-600 text-white px-4 py-2 rounded-lg font-medium">{children}</button>;
}
// usage
<Button>Save</Button>Vérification rapide
Vérifiez votre compréhension des pièges et des alternatives de @apply.
Récapitulatif de la leçon
Dans cette leçon, vous avez appris que les pièges de @apply incluent la reproduction du CSS traditionnel, la dissimulation des styles pour les lecteurs du HTML et l’absence de prise en charge des valeurs arbitraires ; que les meilleures alternatives sont les composants JSX avec clsx pour React ou les fragments de modèles pour les applications générées côté serveur ; et que @apply doit être réservé au HTML que vous ne pouvez pas contrôler, comme le Markdown généré par un CMS. Nous allons maintenant étudier les utilitaires de transition et d’animation de Tailwind.
Apprends HTML avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 30
- Leçons
- 120
Questions Fréquemment Posées
La leçon « Pièges et alternatives de @apply » est-elle gratuite ?
Oui — le texte complet de « Pièges et alternatives de @apply » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Tailwind CSS Academy, passe à CoddyKit PRO. Le cours Tailwind CSS Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Pièges et alternatives de @apply » ?
Identifiez les utilisations courantes et incorrectes de @apply, comprenez les effets sur la spécificité et évaluez les alternatives d’extraction de composants, comme les composants JSX. Tu pratiques Tailwind CSS Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Tailwind CSS Academy ?
Aucune expérience préalable n'est requise. Tailwind CSS Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Pièges et alternatives de @apply » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Tailwind CSS Academy ?
Oui. Chaque leçon Tailwind CSS Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Rôle de @apply et situations d’utilisation
- Créer des classes de composants réutilisables
- Organiser les CSS personnalisées avec des couches
- Pièges et alternatives de @apply