Plan de migration vers Tailwind CSS v4 đ : la mĂ©thode (presque) sans douleur
Ăa y est, le grand jour est arrivĂ©âŻ! Vous avez enfin dĂ©cidĂ© de vous attaquer Ă cette fameuse dette technique qui vous fait faire des cauchemars la nuit. đ
Beaucoup de nos projets (et sans doute les vĂŽtres) reposent encore sur dâanciens frameworks CSS basĂ©s sur Sass, comme Bootstrap v4 ou dâautres solutions maison (coucou Atomic Builder đ). Et soyons honnĂȘtes : maintenir et mettre Ă jour ces projets relĂšve souvent du parcours du combattant. On fait face Ă un manque cruel de flexibilitĂ©, la dette technique sâaccumule, et les dĂ©pendances commencent Ă poser plus de soucis quâelles nâen rĂ©solvent.
Sans oublier que Sass, bien quâayant Ă©tĂ© notre fidĂšle compagnon pendant de trĂšs (trĂšs) nombreuses annĂ©es, devient de moins en moins indispensable avec lâĂ©volution fulgurante du CSS natif. Nous avons dâailleurs eu lâoccasion dâen parler dans notre article expliquant pourquoi passer Ă PostCSS.
Le choix sâest donc naturellement portĂ© vers Tailwind CSS v4. Câest une solution qui a fait ses preuves chez JoliCode (Jâai testĂ© Tailwind CSS) et, cerise sur le gĂąteau, cette nouvelle version ne nĂ©cessite aucune dĂ©pendance liĂ©e Ă Sass.
LâannĂ©e derniĂšre, nous avons amorcĂ© des phases de migration pour plusieurs de nos projets clients. Aujourdâhui, jâai envie de partager avec vous quelques retours dâexpĂ©rience et une mĂ©thodologie (testĂ©e et approuvĂ©e â ) pour que ces migrations se passent le mieux possibleâŻ!
Section intitulĂ©e phase-1-migration-des-feuilles-de-styles-cssPhase 1 : Migration des feuilles de styles CSS đš
Lâobjectif de cette premiĂšre phase est simple : utiliser du CSS natif et dire officiellement au revoir Ă notre bon vieux Sass. đ
La toute premiÚre étape consiste à migrer la configuration globale de votre projet (généralement définie dans des fichiers tels que variables.scss ou global.scss) vers un systÚme basé sur des custom properties (variables CSS), en ciblant la racine du document HTML via la pseudo-classe :root.
Avant (Sass) :
$color-primary: #f7d325;
$color-secondary: #ff2951;
$font-family-sans-serif: "Source Sans Pro", sans-serif;
AprĂšs (CSS natif) :
:root {
--color-primary: #f7d325;
--color-secondary: #ff2951;
--font-sans: "Source Sans Pro", sans-serif;
}
Info
Utilisez dĂšs maintenant la nomenclature de Tailwind CSS v4 pour nommer vos variables CSS. Ăa vous fera gagner un temps prĂ©cieux pour la suite. đ
Section intitulée cas-n-1-les-variables-et-fonctionsCas n°1 : Les variables et fonctions
Une fois votre thĂšme mis en place, votre premiĂšre mission sera de remplacer tous vos $ par des var(--). Câest aussi lâoccasion de traduire vos fonctions Sass en CSS moderne. đ
Avant (Sass) :
.button {
width: math.div(100%, 3);
background-color: $color-primary;
&:hover,
&:focus-visible,
&:active {
background-color: darken($color-primary, 15%);
}
}
AprĂšs (CSS natif) :
.button {
/* Le CSS natif s'occupe des calculs dynamiquement ! */
width: calc(100% / 3);
background-color: var(--color-primary);
&:hover,
&:focus-visible,
&:active {
/* Magie ! Les couleurs relatives en CSS natif */
background-color: hsl(from var(--color-primary) h s calc(l - 15));
}
}
Aujourdâhui, le CSS natif est devenu suffisamment mature pour remplacer la quasi-totalitĂ© des fonctions Sass. Câest particuliĂšrement vrai pour les manipulations de couleurs, qui sâĂ©crivent dĂ©sormais trĂšs simplement grĂące aux couleurs relatives en CSS. đš
Section intitulĂ©e cas-n-2-le-piege-du-selecteur-d-imbrication-code-amp-code-et-du-bemCas n°2 : Le piĂšge du sĂ©lecteur dâimbrication & et du BEM
La bonne nouvelle, câest que le CSS natif gĂšre dĂ©sormais trĂšs bien le nesting (lâimbrication). Lâesperluette (&) pour cibler des Ă©tats comme &:hover ou &:focus fonctionne parfaitement sans Sass.
La mauvaise nouvelle� Si vous utilisiez le & pour concaténer des classes, typiquement avec la méthodologie BEM (&__element ou &--modifier), le CSS natif ne comprendra pas cette syntaxe. Il va falloir « désimbriquer » ces éléments.
Avant (Sass) :
.link {
color: $color-primary;
&:hover,
&:focus-visible,
&:active {
color: $color-secondary;
}
/* Sass va compiler ce code en ".link--secondary" */
&--secondary {
color: $color-secondary;
}
}
AprĂšs (CSS natif) :
.link {
color: var(--color-primary);
/* Ce code fonctionne toujours en CSS natif ! */
&:hover,
&:focus-visible,
&:active {
color: var(--color-secondary);
}
}
/* Il faut sortir la classe enfant de l'imbrication */
.link--secondary {
color: var(--color-secondary);
}
Section intitulée cas-n-3-les-media-queriesCas n°3 : Les media queries
Pour les media queries gĂ©nĂ©rĂ©es via des mixins ou des fonctions Sass (du type @include media-breakpoint-up(md)), passez simplement les valeurs en dur pour le moment (@media (min-width: 768px)). Nous nous en occuperons plus tard, lors de lâintĂ©gration de Tailwind.
Section intitulée cas-n-4-les-mixins-boucles-et-regles-complexesCas n°4 : Les mixins, boucles et rÚgles complexes
Pour les cas trÚs spécifiques (boucles @for, mixins complexes), la solution la plus pragmatique est de récupérer la version déjà compilée et de la coller dans votre fichier CSS.
Avant (Sass) :
@for $i from 1 through 3 {
.button--size-#{$i} {
padding: #{$i}rem;
}
}
AprĂšs (CSS natif) :
.button--size-1 { padding: 1rem; }
.button--size-2 { padding: 2rem; }
.button--size-3 { padding: 3rem; }
Ă la fin de cette phase, le code CSS de votre projet nâutilise techniquement plus aucune fonctionnalitĂ© propre Ă Sass. đ
Section intitulĂ©e phase-2-migration-provisoire-des-classes-utilitairesPhase 2 : Migration (provisoire) des classes utilitaires đ§°
Câest lâĂ©tape de la « prise de masse » avant la sĂšche. đȘ
LâidĂ©e est de rĂ©cupĂ©rer le CSS compilĂ© de toutes les classes utilitaires de votre ancien framework et de les stocker dans un nouveau dossier, par exemple utilities/. Pour garder lâesprit clair, sĂ©parez-les par thĂ©matique : utilities/typography.css, utilities/spacing.css, etc.
Exemple dâun fichier utilities/spacing.css (rĂ©cupĂ©rĂ© depuis Bootstrap v4) :
.mt-1 { margin-top: 0.25rem !important; }
.mt-2 { margin-top: 0.5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
/* ... */
Votre CSS global va grossir temporairement. Câest normal, ne paniquez pasâŻ! Ces fichiers agiront comme un filet de sĂ©curitĂ© visuel en attendant que Tailwind prenne le relais. đźâđš
Section intitulĂ©e phase-3-on-debranche-l-ancien-framework-cssPhase 3 : On dĂ©branche lâancien framework CSS đ
Si les phases 1 et 2 ont Ă©tĂ© faites minutieusement, vous pouvez supprimer lâancien framework CSS de vos dĂ©pendances. Visuellement, rien ne devrait bouger. đ€
Avertissement
Attention aux comportements JSâŻ! Si votre ancien framework (comme Bootstrap) gĂ©rait des modales, des info-bulles ou des menus dĂ©roulants, la suppression de son CSS (et de ses scripts associĂ©s) risque de casser les animations ou le positionnement. PrĂ©voyez un peu de temps de dĂ©veloppement pour vĂ©rifier les interactions JavaScript et réécrire ces quelques composants. Profitez-en pour utiliser du JS vanilla ou du CSS moderne (lâAPI Popover native est parfaite pour ça, par exempleâŻ!).
Section intitulĂ©e phase-4-l-adieu-a-sassPhase 4 : Lâadieu Ă Sass đ«Ą
Câest lâheure de dĂ©sinstaller une fois pour toutes sass (ou node-sass). Nâoubliez pas de renommer tous vos fichiers .scss en .css.
Lors de cette Ă©tape, il est trĂšs probable que le compilateur Ă©choue lors de son premier lancement. Si la console se remplit dâerreurs, pas de panique, câest un grand classiqueâŻ! Cela sâexplique gĂ©nĂ©ralement par lâune de ces trois raisons :
- Lâimport fantĂŽme : Votre bundler (comme Webpack) ou votre point dâentrĂ©e JavaScript (le fameux
app.js) pointe toujours vers un fichier portant lâextension.scss. Pensez Ă bien mettre Ă jour vos chemins dâimportation. - Le reliquat de Sass : Il reste quelques
$,@use, etc. qui traĂźnent dans vos fichiers CSS. Pensez Ă les supprimer. - Les commentaires : Les commentaires dâune seule ligne Ă©crits avec
//étaient valides avec Sass, mais pas avec votre CSS natif.
Lâerreur classique Ă corriger :
// Ce commentaire était valide en Sass, mais fera planter votre CSS natif !
.element { color: var(--color-primary); }
/* Remplacez-le par la syntaxe standard ! */
.element { color: var(--color-primary); }
Une fois ces petits ajustements faits, respirez un grand coup. Le plus dur techniquement est derriĂšre vous. đ
Section intitulĂ©e phase-5-l-entree-en-scene-de-tailwind-css-v4Phase 5 : LâentrĂ©e en scĂšne de Tailwind CSS v4 đ€©
Il est enfin temps dâinstaller Tailwind CSS v4 et PostCSS (indispensable dans nos projets Symfony avec Webpack Encore). Je vous conseille de suivre la documentation officielle pour le setup initial.
Section intitulĂ©e le-piege-de-l-import-global-et-du-preflightLe piĂšge de lâimport global (et du Preflight)
La documentation officielle vous recommandera dâimporter Tailwind de cette façon :
@import "tailwindcss";
En utilisant cet import global, Tailwind embarque par dĂ©faut plusieurs layers CSS (theme, base, components et utilities), injectant par la mĂȘme occasion son propre reset CSS (Preflight). Si votre projet possĂ©dait dĂ©jĂ un fichier de reset (comme normalize.css), vous risquez dâavoir des conflits.
Info
DĂ©sactivez Preflight dans un premier temps, ainsi que lâensemble des layers CSS importĂ©s pour limiter les rĂ©gressions et les problĂ©matiques liĂ©es Ă la cascade CSS.
Pour cela, privilégiez des imports ciblés (sans les layers CSS) :
@import "tailwindcss/theme.css";
@import "tailwindcss/utilities.css";
Section intitulée la-magie-de-la-directive-code-theme-codeLa magie de la directive @theme
La rĂ©volution de la v4, câest quâelle est CSS-first. Fini lâĂ©norme fichier tailwind.config.js Ă la racine de votre projetâŻ! Le thĂšme que vous aviez anticipĂ© lors de la phase 1 sâintĂšgre dĂ©sormais presque nativement grĂące Ă la nouvelle directive @theme.
Avant :
:root {
--color-primary: #f7d325;
--color-secondary: #ff2951;
--font-sans: "Source Sans Pro", sans-serif;
}
AprĂšs :
@theme static {
--color-primary: #f7d325;
--color-secondary: #ff2951;
--font-sans: "Source Sans Pro", sans-serif;
}
Info
Gardez vos variables CSS accessibles partoutâŻ! Pensez Ă gĂ©nĂ©rer vos variables CSS avec le comportement static, comme indiquĂ© dans la documentation Tailwind. Ainsi, elles ne seront pas limitĂ©es aux classes utilitaires de Tailwind, mais resteront utilisables partout dans vos propres composants CSS personnalisĂ©s.
Câest aussi le moment parfait pour utiliser la directive @variant afin dâuniformiser ces fameuses media queries que nous avions mises en dur plus tĂŽtâŻ!
Avant :
@media (min-width: 768px) {
.card {
color: var(--color-primary);
}
}
AprĂšs :
@variant md {
.card {
color: var(--color-primary);
}
}
Ce petit changement vous garantit que tout votre CSS sur-mesure restera parfaitement synchronisé avec le comportement natif des classes utilitaires de Tailwind.
Section intitulĂ©e phase-6-le-nettoyage-de-printempsPhase 6 : Le nettoyage de printemps đ§č
Je prĂ©fĂšre ĂȘtre honnĂȘte : cette Ă©tape demande de la patience. đ
Lâobjectif est de supprimer le dossier utilities/ créé Ă la phase 2. Pour ce faire, vous allez devoir remplacer dans tous vos templates HTML/Twig les anciennes classes par les nouvelles gĂ©nĂ©rĂ©es par Tailwind.
Vos meilleurs alliĂ©s ici seront lâoutil de recherche de votre IDE, les expressions rĂ©guliĂšres (Regex), et bien sĂ»r votre LLM (Large Language Model) favori (ChatGPT, Claude, GitHub Copilot, etc.) pour automatiser un maximum le processus.
Avant (Bootstrap v4) :
<div class="d-flex flex-column flex-md-row">...</div>
AprĂšs (Tailwind CSS v4) :
<div class="flex flex-col md:flex-row">...</div>
Section intitulĂ©e le-boss-final-les-grillesLe boss final : Les grilles đ
Il nây a pas de solution magique ici. Les vieux frameworks utilisaient gĂ©nĂ©ralement Flexbox pour simuler un comportement de grille. Tailwind, lui, utilise le module natif CSS Grid Layout (modĂšle de disposition en grille).
Il va falloir repasser sur vos grilles manuellement. đŹ
Lâancienne approche (Flexbox) :
<div class="row">
<div class="col-12 col-md-6">...</div>
<div class="col-12 col-md-6">...</div>
</div>
La nouvelle approche (Grid) :
<div class="grid grid-cols-1 md:grid-cols-2">
<div>...</div>
<div>...</div>
</div>
Câest fastidieux, mais le DOM en ressort considĂ©rablement allĂ©gĂ© et plus lisible. đ„ł
Section intitulĂ©e conclusion-tout-ca-pour-caConclusion : Tout ça pour çaâŻ? đ€
Oui, mille fois oui. Migrer vers Tailwind CSS v4 nâest pas un parcours de santĂ© pour un projet existant. Mais les avantages sont colossaux.
Vous dites adieu Ă lâusine Ă gaz quâĂ©tait devenu Sass au fil des annĂ©es. Le poids final de votre CSS sera drastiquement rĂ©duit puisque Tailwind ne compile que ce que vous utilisez rĂ©ellement. Sans parler des performances pures : avec son nouveau moteur Ă©crit en Rust, les temps de compilation sont si rapides quâon les remarque Ă peine.
Enfin, la Developer Experience (DX) de vos Ă©quipes sâen trouvera transformĂ©e. Câest un investissement en temps consĂ©quent, mais câest un cadeau inestimable que vous faites au futur de votre projet. đ
Section intitulée et-concretement-comment-on-vend-ca-a-sa-directionEt concrÚtement, comment on vend ça à sa direction�
Câest souvent la question qui fĂąche. On sait que le chantier est nĂ©cessaire, mais il est difficile dâestimer le temps que cela va prendre sans y laisser des plumes, dâoĂč lâeffet tunnel qui effraie les Ă©quipes produit.
Pour dĂ©bloquer la situation, nous avons lâhabitude chez JoliCode de commencer par un audit flash (1 Ă 2 jours). Lâobjectif est de poser les choses Ă plat pour vous fournir un plan de bataille concret Ă dĂ©fendre en interne :
- Un état des lieux clair de la dette front actuelle (dépendances, risques, obsolescence).
- Une estimation chiffrée de la migration, découpée par phase.
- Un plan de déploiement progressif qui ne bloque pas votre roadmap produit.
- Les bénéfices attendus (gains de performance, vélocité des équipes, etc.).
Si vous avez besoin dâaide pour cadrer votre propre migration, nâhĂ©sitez pas Ă nous faire signeâŻ!
JâespĂšre que ce retour dâexpĂ©rience vous sera utile et vous donnera le courage de sauter le pas. NâhĂ©sitez pas Ă partager vos propres astuces ou vos galĂšres de migration dans les commentairesâŻ! đ
Commentaires et discussions
Ces clients ont profité de notre expertise
Nous avons entrepris une refonte complĂšte du site, initialement dĂ©veloppĂ© sur Drupal, dans le but de le consolider et de jeter les bases dâun avenir solide en adoptant Symfony. La plateforme est hautement sophistiquĂ©e et propose une plĂ©thore de fonctionnalitĂ©s, telles que la gestion des abonnements avec Stripe et Paypal, une API pour lâapplicationâŠ
Refonte complĂšte de la plateforme dâannonces immobiliĂšres de Cushman & Wakefield France. ConnectĂ© aux outils historiques, cette nouvelle vitrine permet une bien meilleure visibilitĂ© SEO et permet la mise en avant dâactifs qui ne pouvaient pas lâĂȘtre auparavant.
LâĂ©quipe dâAlain Afflelou a choisi JoliCode comme rĂ©fĂ©rent technique pour le dĂ©veloppement de son nouveau site internet. Ce site web-to-store incarne lâimage premium de lâenseigne, met en valeur les collections et offre aux clients de nouvelles expĂ©riences et fonctionnalitĂ©s telles que lâe-rĂ©servation, le store locator, le click & collect et lâessayageâŠ