2e étageTW Tailwind CSSPièce 5/6Avancé

Bonnes pratiques

Éviter la répétition avec des composants, comprendre pourquoi les classes dynamiques échouent et contrôler la détection avec @source.

Ce que tu vas apprendre

  • Réutiliser des styles avec des composants plutôt qu'avec @apply.
  • Écrire des classes qui seront bien détectées, même quand elles varient.
  • Utiliser @source pour dire à Tailwind où chercher.

Le problème de la répétition

La même liste de classes apparaît souvent dans plusieurs endroits :

<a class="rounded-full bg-orange-500 px-5 py-2 font-semibold text-white hover:bg-orange-600">Voir</a>
<a class="rounded-full bg-orange-500 px-5 py-2 font-semibold text-white hover:bg-orange-600">Lire</a>
<a class="rounded-full bg-orange-500 px-5 py-2 font-semibold text-white hover:bg-orange-600">Cuisiner</a>

Avant de chercher une astuce, demande-toi si c'est vraiment un problème. Les solutions ci-dessous suivent l'ordre conseillé par la documentation de Tailwind.

Les solutions, de la meilleure à la dernière

SituationSolution
Le même élément dans une boucleÉcris-le une fois, dans la boucle
Quelques éléments dans un seul fichierModifie-les ensemble (multi-curseur)
Le même élément dans plusieurs fichiersUn composant
Un cas très simple, sans structureUne classe CSS personnalisée

La boucle d'abord : en Vue, v-for écrit la liste de classes une seule fois.

app/pages/recettes/index.vue
<template>
  <ul class="grid gap-4 md:grid-cols-3">
    <li v-for="recette in recettes" :key="recette.id"
        class="rounded-lg border p-4 shadow-md">
      {{ recette.titre }}
    </li>
  </ul>
</template>

Préférer un composant

Quand le même bloc sert dans plusieurs fichiers, fais-en un composant : un fichier qui contient à la fois le HTML et ses classes.

app/components/BoutonPrincipal.vue
<template>
  <a class="rounded-full bg-orange-500 px-5 py-2 font-semibold text-white hover:bg-orange-600">
    <slot />
  </a>
</template>

Dans une page, tu écris <BoutonPrincipal>Voir</BoutonPrincipal>. Pour changer le bouton partout, tu modifies un seul fichier. Dans Nuxt, les composants de app/components/ sont importés automatiquement.

Et @apply ?

La directive @apply copie des classes utilitaires dans une règle CSS à toi :

.bouton-principal {
  @apply rounded-full bg-orange-500 px-5 py-2 font-semibold text-white;
}

Elle sert surtout à styler un code que tu ne contrôles pas, comme les classes d'une bibliothèque tierce. Pour tes propres éléments, un composant est préférable : tu gardes la structure et le style au même endroit, sans nommer de classe ni retourner chercher le CSS.

Dans la page « Reusing styles », la documentation de Tailwind recommande les boucles, puis les composants. Pour un cas simple, elle propose une classe CSS écrite dans @layer components, qui s'appuie sur les variables du thème comme var(--color-violet-500).

Les classes dynamiques ne sont pas détectées

Tailwind ne fait pas tourner ton code. Il lit les fichiers comme du texte et cherche les mots qui ressemblent à des classes. Une classe qu'il ne voit pas écrite en entier n'est pas générée.

Ce code est faux :

<div class="text-{{ erreur ? 'red' : 'green' }}-600"></div>

Les chaînes text-red-600 et text-green-600 n'existent nulle part dans le fichier. Tailwind ne les génère pas et le texte reste sans couleur.

Écris toujours les noms complets :

<div class="{{ erreur ? 'text-red-600' : 'text-green-600' }}"></div>

Correspondre une propriété à des classes entières

Pour un composant dont la couleur change selon une propriété, associe chaque valeur à ses classes complètes :

const variantes = {
  orange: "bg-orange-600 hover:bg-orange-500",
  vert: "bg-green-600 hover:bg-green-500",
}
// puis : variantes[couleur]

Évite la construction par morceaux, comme `bg-${couleur}-600` : les classes finales n'apparaissent jamais en entier.

Si une couleur ou un style n'apparaît pas alors que la classe te semble correcte, cherche d'abord une classe assemblée à la volée.

@source : indiquer où chercher

Tailwind analyse automatiquement les fichiers de ton projet. Pour qu'il lise aussi un dossier qu'il ignore, comme une bibliothèque installée, utilise @source :

@import "tailwindcss";
@source "../node_modules/@acmecorp/ui-lib";

Le chemin est relatif au fichier CSS. À l'inverse, @source not exclut un dossier :

@source not "../src/components/legacy";

Forcer une classe : @source inline

Si une classe n'apparaît nulle part en entier dans ton code (par exemple lue depuis une base de données), force-la :

@source inline("underline");
@source inline("{hover:,}bg-red-{50,{100..900..100},950}");

La deuxième ligne génère bg-red-50, bg-red-100 à bg-red-900 par pas de 100, bg-red-950, et leurs versions hover:.

Désactiver la détection automatique

Pour tout déclarer toi-même, par exemple avec plusieurs feuilles de style :

@import "tailwindcss" source(none);
@source "../admin";
@source "../shared";

Chaque feuille ne contient alors que les classes de ses dossiers.

À retenir

  • Une classe répétée n'est pas toujours un problème : une boucle règle déjà beaucoup de cas.
  • Pour réutiliser entre fichiers, fais un composant plutôt que @apply.
  • Tailwind lit le texte des fichiers : écris les noms de classes complets, jamais assemblés (text-${x}-600).
  • @source ajoute un dossier à analyser, @source not en exclut un.
  • @source inline(...) force la génération d'une classe, et source(none) désactive la détection automatique.

Pour aller plus loin

Sources officielles

Ensuite

Projet
Lignes de code
Niveau
2e étage
Appartement
Tailwind CSS
Pièce
5/6
Plan n°
tailwind/06.bonnes-pratiques
Lignes de code · fiches rédigées à partir des documentations officielles, sources citées en bas de chaque page.