💻 Développement

dev-tailwind-expert

Maîtrise de Tailwind CSS — utility-first, configuration custom, plugins, responsive design et dark mode.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-tailwind-expert --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-tailwind-expert -Launch"

🚀 Déjà installé ?

claude "/dev-tailwind-expert"

Ou tapez /dev-tailwind-expert dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

TailwindTailwind CSSutility-firsttailwind.configclasses Tailwind

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-tailwind-expert ~/.claude/skills/

Payload du plugin : skills/dev-tailwind-expert · source éditable : dev-skills/tailwind-expert

📖 Manuel

Tailwind CSS Expert

Workflow

1. Initialiser le projet

# Tailwind v4 (2025+) — recommandé pour tous les nouveaux projets
npm install tailwindcss @tailwindcss/vite
# OU avec PostCSS
npm install tailwindcss postcss autoprefixer
npx tailwindcss init -p

Critère de décision v3 vs v4 :

2. Configurer tailwind.config.ts

// tailwind.config.ts (v3)
import type { Config } from 'tailwindcss'

export default {
  content: [
    './src/**/*.{ts,tsx,html}',
    './node_modules/@acme/ui/dist/**/*.js', // libs externes si nécessaire
  ],
  darkMode: 'class', // ou 'media'
  theme: {
    extend: {
      colors: {
        brand: {
          50: '#f0f9ff',
          500: '#0ea5e9',
          900: '#0c4a6e',
        },
        destructive: 'hsl(var(--color-destructive) / <alpha-value>)',
      },
      fontFamily: {
        sans: ['Inter Variable', 'system-ui', 'sans-serif'],
      },
      screens: {
        xs: '480px', // breakpoint custom avant sm
      },
    },
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
  ],
} satisfies Config

En v4 (CSS-first) : la config se fait dans le CSS directement :

/* app.css */
@import "tailwindcss";
@theme {
  --color-brand-500: oklch(62% 0.19 240);
  --font-sans: "Inter Variable", system-ui, sans-serif;
}

3. Construire les design tokens

Principe : définir une fois, utiliser partout via des variables CSS ou tokens Tailwind.

// Couleurs sémantiques → mappe les tokens sur des rôles
colors: {
  primary: 'hsl(var(--primary) / <alpha-value>)',
  'primary-foreground': 'hsl(var(--primary-foreground) / <alpha-value>)',
}
/* globals.css */
:root {
  --primary: 221 83% 53%;
  --primary-foreground: 0 0% 100%;
}
.dark {
  --primary: 217 91% 70%;
}

4. Implémenter les composants

Mobile-first systématique :

<!-- Mauvais : pas de base mobile -->
<div class="lg:flex lg:gap-8">...</div>

<!-- Bon : mobile d'abord, puis breakpoints -->
<div class="flex flex-col gap-4 md:flex-row md:gap-8">...</div>

Composition conditionnelle avec cn (clsx + tailwind-merge) :

import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

// Utilisation
<button className={cn(
  'px-4 py-2 rounded-md font-medium transition-colors',
  variant === 'primary' && 'bg-brand-500 text-white hover:bg-brand-600',
  variant === 'ghost'   && 'bg-transparent text-brand-500 hover:bg-brand-50',
  disabled && 'opacity-50 cursor-not-allowed',
)}>

Groupes et peer :

<!-- group-hover : effet parent → enfant -->
<div class="group rounded-lg border p-4 hover:border-brand-500">
  <p class="text-gray-500 group-hover:text-brand-500">Texte</p>
</div>

<!-- peer : état sibling input → label -->
<input id="email" class="peer" required />
<p class="hidden peer-invalid:block text-red-500 text-sm">Email invalide</p>

5. Dark mode

// tailwind.config.ts
darkMode: 'class' // toggle via JS — meilleure UX
// Hook de toggle (React)
function useDarkMode() {
  const toggle = () => document.documentElement.classList.toggle('dark')
  return toggle
}
<!-- Classes dark: sur chaque token de couleur -->
<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">

6. Plugins custom

// Plugin utilitaires — ex: text-balance manquant en v3
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(({ addUtilities, matchUtilities, theme }) => {
      // Utilitaire statique
      addUtilities({
        '.text-balance': { 'text-wrap': 'balance' },
        '.scrollbar-none': { 'scrollbar-width': 'none' },
      })
      // Utilitaire dynamique avec valeur config
      matchUtilities(
        { 'grid-cols-auto': (value) => ({ gridTemplateColumns: `repeat(auto-fill, minmax(${value}, 1fr))` }) },
        { values: theme('spacing') }
      )
    }),
  ],
}
// Usage : <div class="grid-cols-auto-64">

7. Optimiser pour la production

# Vérifier la taille du CSS généré
npx tailwindcss -i ./src/app.css -o ./dist/out.css --minify
du -sh dist/out.css  # objectif : < 20 KB en prod typique

# Analyser les classes non purgées (safelist si nécessaire)
// Safelist pour classes générées dynamiquement (ex: couleur depuis DB)
safelist: [
  'bg-red-500', 'bg-green-500', 'bg-blue-500',
  { pattern: /^(bg|text|border)-(brand|destructive)-\d{2,3}$/ },
]

Règle @apply : uniquement pour les composants de base répétés dans des fichiers .css — jamais dans des composants JSX.

/* base.css — OK */
.btn-primary {
  @apply px-4 py-2 bg-brand-500 text-white rounded-md hover:bg-brand-600;
}

8. Ordre et maintenabilité

Ordre recommandé (Prettier plugin enforce automatiquement) :

npm install -D prettier-plugin-tailwindcss
Layout (display, position) → Flexbox/Grid → Sizing → Spacing → Typography → Colors → Effects → Interactions

Anti-patterns et pièges

PiègeProblèmeSolution
Classes dynamiques par concaténation de stringPurgées en prodUtiliser des classes complètes ou safelist
@apply dans chaque composant JSXAnnule le bénéfice utility-firstGarder les styles inline en JSX
Override sans extendSupprime les valeurs Tailwind par défautToujours utiliser theme.extend
Ignorer tailwind-mergeConflits de classes (p-2 p-4 → imprévisible)Toujours passer par cn()
Breakpoints hors mobile-firstCSS incohérentBase sans préfixe = mobile, puis sm: et au-delà
Hardcoder des couleurs hex en classesPas thémableDéfinir dans tailwind.config ou @theme

Bonnes pratiques 2026

<!-- Container query v4 -->
<div class="@container">
  <div class="grid grid-cols-1 @sm:grid-cols-2 @lg:grid-cols-3">...</div>
</div>