Il y a huit ans, Julia Evans publiait un billet enthousiaste sur sa découverte de Tailwind, qu'elle résumait alors comme une manière de styler un site sans écrire de CSS.2 Mi-mai, elle a pris le chemin inverse : en une semaine environ, elle a migré quelques-uns de ses sites vers du HTML sémantique et du CSS écrit à la main.1 Le plus intéressant de l'histoire n'est pas le départ. C'est ce qu'elle a emporté en partant : la feuille de reset de Tailwind, son échelle typographique, jusqu'à sa classe utilitaire pour lecteurs d'écran, toutes recopiées dans de simples fichiers CSS qu'elle entretient désormais elle-même.1
Pourquoi partir
Ses raisons manquent singulièrement de glamour. Depuis 2018, Tailwind dépend bien davantage d'un build system, au point qu'elle estime, avec son propre point d'interrogation écrit noir sur blanc, que les versions récentes sont inutilisables sans lui. Elle n'a jamais suivi ce mode de travail : elle est restée des années sur Tailwind v2 et livrait la feuille complète quand même, des fichiers tailwind.min.css de 2,8 Mo (270 Ko gzip) qui traînaient dans beaucoup de ses projets. Un peu ridicule, admet-elle.1
Le reste de la liste tient en quelques lignes : elle écrit tout simplement bien mieux CSS qu'en 2018 ; les limites du framework gênent ce qu'elle appelle le Weird Stuff ; entretenir des projets mélangeant Tailwind et CSS vanilla n'était plus tenable ; et elle voulait voir ce que donnerait un HTML plus sémantique.1
Ce récit a d'ailleurs un second acte, parce qu'elle avait documenté elle-même le point de départ. Son billet de 2018 célèbre la première version de sa boutique de zines, montée en deux soirées, avec Tailwind arrivant sous forme d'un unique lien CDN et sans aucune étape de build. À l'époque, elle googlait « how do I center div » pour ce qu'elle dit être la cinq-centième fois et décrivait son HTML de secours comme des div portant des ids du genre WRAPPER-WRAPPER-THING.2
Copié, pas inventé
Au moment de structurer son propre CSS, Evans découvre que son intimidation était mal placée. Tout projet CSS mélange déjà des layouts, des polices, des couleurs et des composants récurrents ; ce qui empêche l'ensemble de basculer dans le chaos, c'est d'avoir un système pour chacun. Et Tailwind, note-t-elle, lui avait déjà donné des systèmes pour une bonne partie de ces besoins.1
La migration commence donc par un vol en plein jour. Elle ouvre la feuille de Tailwind et recopie les deux cents premières lignes, le fameux reset preflight, dans son propre projet. Elle soupçonne qu'une partie de ces règles vit dans ses réflexes sans qu'elle l'ait jamais remarqué : chaque élément passé en box-sizing: border-box, le line-height par défaut à 1,5.1
Ce détail mérite une pause. Une développeuse qui quitte un framework raconte d'habitude une libération vis-à-vis de décisions arbitraires. Ici, le framework s'avérait prendre des centaines de petites décisions avec lesquelles elle était d'accord, et le geste honnête consiste à les assumer explicitement plutôt qu'à les redécouvrir par accident.
Un fichier par composant
L'essentiel de son nouveau CSS suit trois règles empruntées, dans l'esprit, aux frameworks à composants : chaque composant reçoit une classe unique, ses styles ne surchargent jamais ceux d'un autre composant, et chacun vit dans son propre fichier. Modifier un élément revient à penser une centaine de lignes, et elle estime qu'environ 80 % du CSS qu'elle veut réellement changer se trouve dans ces fichiers de composants.1
Rien ne garantit cette discipline. Pas de web components, pas de @scope, juste une convention qu'elle essaie de respecter. Cela lui suffit : la convention seule représente déjà un progrès net face au risque de collision invisible.
Autour des composants, les couches de support restent volontairement minuscules. Toutes les couleurs doivent figurer dans un seul colours.css. Les tailles de police proviennent de variables reprises telles quelles de l'échelle Tailwind, --size-xs: 0.75rem et consorts, plus verbeuses que text-lg mais acceptables selon elle.1
La couche « base », celle qui s'applique à tout le site, est la plus petite de toutes : exactement deux règles qu'elle se sent capable d'imposer, une colonne centrale de 950 pixels pour les sections et des liens orange. Son plan consiste à la faire grossir par le bas, en n'y promouvant que des styles dont la généralité est prouvée.1
Grilles contre breakpoints
La rupture la plus nette avec ses années Tailwind concerne le responsive. Avant, elle s'appuyait sur des utilitaires média comme md:text-xl, en décidant élément par élément du comportement à chaque taille. Désormais, elle construit des grilles flexibles qui s'adaptent presque sans breakpoints, par exemple repeat(auto-fit, minmax(min(100%, 400px), max-content)), qui tranche entre une et deux colonnes selon la place disponible. Elle utilise aussi beaucoup grid-template-areas, une fonctionnalité qu'elle juge géniale et ne croit pas offerte par Tailwind.1
L'espacement reste, de son propre aveu, un chantier ouvert. Son principe actuel repousse la responsabilité vers les composants de layout extérieurs, avec des astuces comme le sélecteur hibou (section > *+* { margin-top: 1rem }) pour espacer régulièrement les enfants. Comparé à l'époque où elle dispersait paddings et margins au hasard jusqu'à ce que la page ait l'air correcte, ainsi qu'elle décrit ses habitudes de l'époque Tailwind, c'est plus principiel. Ce n'est pas encore un système.1
La question du build se résout avec le même pragmatisme. Le développement n'exige rien : le CSS supporte désormais nativement les imports et le nesting. Pour la production, elle peut bundler avec esbuild, outil qu'elle accepte malgré sa méfiance générale pour les build systems parce qu'il colle aux standards web et s'installe comme un binaire Go statique.1
La raison de fond
Tout ce qui précède pourrait se lire comme un exercice d'optimisation. Evans est explicite : la raison la plus profonde siège ailleurs. Il y a trois ans, elle a lu l'essai d'Elaina Natario sur Tailwind et la féminité du CSS, qui soutient, en empruntant les mots de Jeremy Keith, que les programmeurs entendent que le CSS est simple, supposent qu'il est facile, et accusent le langage quand il leur résiste. Cet essai ne l'a pas lâchée.13
Sa réponse, pendant une décennie, a été de prendre le CSS au sérieux comme technologie au lieu de le dévaloriser. L'apprendre correctement a dissous ses vieilles frustrations : le centrage était résolu depuis longtemps, de plusieurs façons, parce que centrer désigne en réalité plusieurs problèmes. « CSS is hard because it's solving a hard problem! »1
Vient ensuite la phrase qui donne tout son poids à la migration. Selon elle, Tailwind contribue à dévaloriser l'expertise CSS, et elle refuse d'y participer, « especially in this time of LLMs where it feels more important than ever to value humans' expertise ».1
Sept cents commentaires
La réception suggère qu'elle a touché quelque chose de partagé. Le thread Hacker News principal a récolté 698 points et 397 commentaires, et Simon Willison citait dès le lendemain son passage sur le respect dû au CSS.45
Ni le thread ni son billet ne règlent la question de Tailwind à grande échelle, et elle ne prétend pas le contraire : sa conclusion concerne ses propres projets, ceux où elle veut désormais des contraintes choisies. Sa liste de prochaines curiosités, cascade layers, @scope, container queries, subgrid, ressemble à une liste de courses que la plateforme prépare patiemment pour exactement ce genre de retour.1
Le framework n'a jamais vraiment quitté son CSS. Il a déménagé : il est devenu des conventions qu'elle peut ouvrir et lire.