Aller au contenu
CSS 1 min de lecture

Tailwind CSS v4 — un design system sans configuration

Thème CSS-first, tokens @theme, custom variants : construire un design system cohérent avec Tailwind v4, sans fichier de config interminable.

Yann LerouxYann LerouxFrontend Engineer

Tailwind v4 change l'équation du design system : la configuration vit dans le CSS, pas dans un fichier JavaScript. Résultat — aucune dépendance de config à maintenir, des tokens visibles pour tout éditeur, et un blog entier qui tient dans une seule feuille de style.

Ce que la v4 change

v3 vs v4 — où vit la configuration

Tailwind v3Tailwind v4
Configurationtailwind.config.js (JS)CSS, via @theme
Importdirectives @tailwind@import "tailwindcss"
Custom variantplugin JS@custom-variant en CSS
Tokens couleurobjet JSvariables CSS dans :root / .dark

Le pari CSS-first est un pari de lisibilité. Ouvrir main.css suffit pour connaître l'entière palette du site — aucun fichier de build à lire.

Construire le système

  1. Importer et poser le variant sombre

  2. Un seul import, et le variant dark piloté par la classe sur <html> (color-mode s'en charge) :

    @import "tailwindcss";
    
    @custom-variant dark (&:where(.dark, .dark *));
    
  3. Déclarer les tokens sémantiques

  4. Les couleurs "raw" vivent dans :root / .dark, les tokens sémantiques dans @theme inline — Tailwind en génère les utilitaires (bg-base, text-muted, border-hairline…) :

    @theme inline {
      --color-base: var(--bg);
      --color-elevated: var(--bg-elevated);
      --color-fg: var(--text);
      --color-muted: var(--text-muted);
      --color-hairline: var(--line);
      --font-display: 'Newsreader', Georgia, serif;
    }
    
  5. Écrire les utilitaires signature

  6. Ce qui fait l'identité du site est du CSS ordinaire — pas de plugin :

    .hairline-t { border-top: 1px solid var(--line); }
    .brand-gradient-bg { background: linear-gradient(135deg, #6366f1, #8b5cf6); }
    

Typographie et rayons : trois familles, une échelle

Le même @theme inline déclare les familles de polices et l'échelle de rayons — deux tokens supplémentaires, zéro fichier supplémentaire :

--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
--font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

--radius-xs: 0.25rem;
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
--radius-2xl: 1.5rem;

L'interface et le corps des articles restent en Inter ; les titres passent en Newsreader, une serif éditoriale qui donne au site son identité de « blog » ; le code est en JetBrains Mono. Et les utilitaires rounded-* de Tailwind suivent l'échelle déclarée — un seul endroit décide si un coin est un rounded-md ou un rounded-2xl.

Les utilitaires signature restent du CSS ordinaire. La grille de points (.dotgrid), le dégradé de marque (.brand-gradient-bg) et les filets (.hairline-*) sont de simples classes, partagées telles quelles avec le site marketing — aucun plugin Tailwind à maintenir des deux côtés.

Le gain concret

Sur ce blog, l'ensemble du design system (deux thèmes, trois familles de polices, une douzaine d'utilitaires) tient dans ~200 lignes de CSS. Le passage clair ↔ sombre est instantané, sans flash, et chaque composant reste un fichier Vue sans logique de thème.

Attention aux tokens non inlinés. Un @theme sans inline émet des variables en :root ; avec inline, Tailwind substitue les valeurs directement — préférez inline pour des tokens qui changent avec le thème, sinon dark: ne les suivra pas.

Pour aller plus loin

Le code de ce blog est un exemple complet : tokens sémantiques, variant dark, utilitaires signature et typographie éditoriale — à réutiliser sans retenue.

tailwind css design-systems
Yann Leroux

Écrit par

Yann Leroux

Frontend Engineer

Yann covers the Vue and Nuxt ecosystem, design systems and CSS. He maintains a few open-source UI utilities and cares deeply about typographic detail.