Comment j'ai arrêté de me battre avec mon CSS
Pendant longtemps, j'ai écrit du CSS à la main. BEM pour la nomenclature, SMACSS pour l'architecture, des fichiers partiels bien rangés dans des dossiers. Ça fonctionnait. Et c'était épuisant à maintenir.
Le problème avec une architecture CSS manuelle, c'est qu'elle tient à la rigueur du développeur dans la durée. Sur un projet solo, ça va. Sur un projet qui s'étale sur plusieurs mois, avec des interruptions, des reprises, des changements de direction : les conventions dérivent, les classes s'accumulent, le fichier CSS grossit et on n'ose plus rien supprimer de peur de casser quelque chose ailleurs.
Tailwind CSS a changé ça pour moi. Pas parce que c'est magique : parce que l'approche utility-first force à penser différemment.
Ce que l'approche utility-first change vraiment
Avec Tailwind, le style est écrit là où il est utilisé. Dans le HTML, dans le template Blade, directement sur l'élément. Ça semble contre-intuitif au départ (c'est ce qu'on nous a appris à éviter), et ça devient évident très vite.
Quand je lis un composant Blade, je vois immédiatement ce qu'il fait visuellement : pas besoin d'ouvrir un fichier CSS séparé, de chercher la bonne classe, de remonter l'héritage. Tout est là. Et quand je supprime un composant, je supprime son style avec lui, automatiquement : zéro CSS mort.
Le coût d'entrée est réel. Les premières heures à mémoriser flex, items-center, gap-4, text-sm, font-medium peuvent décourager. Après une semaine, c'est devenu un réflexe. Après un mois, retourner à du CSS manuel donne l'impression de régresser.
Ce que la v4 a changé
La version 4 de Tailwind CSS est une rupture propre avec la configuration JavaScript des versions précédentes.
Avant, tout passait par tailwind.config.js : définition du thème, des couleurs personnalisées, des breakpoints, des plugins. C'était lisible, mais c'était une couche de configuration supplémentaire à maintenir, à documenter, à synchroniser avec l'équipe ou avec soi-même six mois plus tard.
Avec la v4, la configuration passe dans le CSS lui-même, via la directive @theme. On définit ses tokens de design directement dans son fichier CSS :
@import "tailwindcss";
@theme {
--color-brand: #06b6d4;
--font-display: 'Inter', sans-serif;
--spacing-18: 4.5rem;
}
C'est du CSS natif, lisible par n'importe quel outil, sans dépendance à la configuration JavaScript. Le fichier tailwind.config.js n'est plus obligatoire pour la majorité des cas d'usage.
L'autre changement majeur : l'intégration Vite est beaucoup plus propre. Le plugin officiel gère la détection des classes utilisées (le "purge" dans l'ancienne terminologie) de façon transparente, sans configuration des chemins à scanner. Sur un projet Laravel avec Vite, c'est une dizaine de lignes de configuration en moins.
Le piège des classes dynamiques
Un point important que j'ai appris à mes dépens et que je mentionne systématiquement dans mes projets : Tailwind ne compile que les classes qu'il détecte statiquement dans les templates.
Si on construit une classe dynamiquement en PHP ou en Blade :
{{-- Ceci ne fonctionnera PAS --}}
<div class="text-{{ $color }}-400">...</div>
La classe text-cyan-400 ne sera jamais incluse dans le CSS de production parce que Tailwind ne l'a jamais vue complète dans le code source.
La solution : écrire les classes complètes, quitte à utiliser des conditions explicites :
{{-- Correct --}}
<div class="{{ $color === 'cyan' ? 'text-cyan-400' : 'text-slate-400' }}">...</div>
C'est une contrainte qui modifie la façon d'écrire les templates. Elle s'intègre naturellement une fois qu'on l'a assimilée.
Pourquoi je ne reviendrai pas en arrière
Sur ce site (vs81.fr), sur Collab (mon outil de gestion de projets), et sur tous les projets clients récents : tout est en Tailwind v4. L'intégration avec Laravel Blade est parfaite, les classes sont prévisibles, la documentation est excellente.
Je ne reviendrai pas à BEM ou SMACSS pour un projet Laravel. Pas parce que ces approches sont mauvaises : parce que Tailwind utility-first + Vite + Blade, c'est une combinaison qui fonctionne si bien ensemble qu'en changer serait accepter une régression sans contrepartie.