MODULE H05
Tailwind CSS
Un framework CSS utility-first : composez des interfaces directement dans votre HTML avec des classes atomiques.
1. Introduction à Tailwind CSS
Tailwind CSS est un framework utility-first : au lieu de classes sémantiques comme .btn, vous composez des styles avec des classes atomiques comme bg-blue-500 px-4 py-2 rounded.
Philosophie Tailwind ne fournit pas de composants prêts à l'emploi. Il donne les briques de base pour construire n'importe quel design sans quitter le HTML.
<!-- Bootstrap (sémantique) -->
<button class="btn btn-primary btn-lg">Cliquer</button>
<!-- Tailwind (utility-first) -->
<button class="bg-blue-600 hover:bg-blue-700 text-white font-semibold
px-6 py-3 rounded-lg transition-colors">
Cliquer
</button>
Avantages
- Pas de CSS à écrire — tout dans le HTML
- Pas de problèmes de spécificité CSS
- Tree-shaking automatique — CSS minimal en production
- Design cohérent grâce au système de design intégré
- Dark mode, responsive, hover intégrés via préfixes
2. Installation
# Via npm (recommandé pour les projets)
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
# Dans tailwind.config.js
module.exports = {
content: ["./src/**/*.{html,js,jsx,tsx}"],
theme: { extend: {} },
plugins: [],
}
/* Dans votre CSS principal (src/input.css) */
@tailwind base;
@tailwind components;
@tailwind utilities;
# Compiler
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch
<!-- Via CDN (prototypage uniquement) -->
<script src="https://cdn.tailwindcss.com"></script>
3. Classes utilitaires essentielles
<!-- ── Espacement ── -->
<!-- p-{n} = padding | m-{n} = margin | {n}: 0,1,2,3,4,5,6,8,10,12,16,20,24,32... -->
<!-- 1 = 0.25rem | 2 = 0.5rem | 4 = 1rem | 8 = 2rem | 16 = 4rem -->
<div class="p-4 m-2 px-6 py-3 mt-8 mx-auto"></div>
<div class="space-y-4"> <!-- gap vertical entre enfants --></div>
<!-- ── Tailles ── -->
<div class="w-full h-screen w-64 h-48 max-w-xl min-h-0"></div>
<div class="w-1/2 w-1/3 w-1/4"></div>
<!-- ── Couleurs ── -->
<!-- text-{color}-{shade} | bg-{color}-{shade} | border-{color}-{shade} -->
<!-- shades: 50,100,200,300,400,500,600,700,800,900,950 -->
<div class="bg-blue-500 text-white border border-blue-600"></div>
<div class="bg-gray-900 text-gray-100"></div>
<div class="bg-emerald-500/20 text-emerald-400"></div> <!-- /20 = opacity 20% -->
<!-- ── Typographie ── -->
<h1 class="text-4xl font-bold tracking-tight leading-tight"></h1>
<p class="text-sm text-gray-500 font-medium"></p>
<span class="uppercase tracking-widest text-xs"></span>
<!-- text-xs sm base lg xl 2xl 3xl 4xl 5xl 6xl -->
<!-- font-thin light normal medium semibold bold extrabold black -->
<!-- ── Bordures ── -->
<div class="border border-gray-200 rounded-lg rounded-full rounded-xl"></div>
<div class="ring-2 ring-blue-500 ring-offset-2"></div>
<!-- ── Ombres ── -->
<div class="shadow-sm shadow shadow-md shadow-lg shadow-xl shadow-2xl"></div>
<!-- ── Overflow ── -->
<div class="overflow-hidden overflow-x-auto truncate"></div>
4. Responsive (Mobile First)
<!-- Préfixes breakpoint: sm: md: lg: xl: 2xl: -->
<!-- sm: ≥640px | md: ≥768px | lg: ≥1024px | xl: ≥1280px | 2xl: ≥1536px -->
<!-- Grille responsive -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
<div class="col-span-1">Card</div>
</div>
<!-- Texte responsive -->
<h1 class="text-2xl md:text-4xl lg:text-5xl font-bold">Titre</h1>
<!-- Layout responsive -->
<div class="flex flex-col md:flex-row gap-4">
<aside class="w-full md:w-64 shrink-0">Sidebar</aside>
<main class="flex-1">Contenu</main>
</div>
<!-- Visibilité responsive -->
<nav class="hidden md:flex gap-6">Menu desktop</nav>
<button class="md:hidden">Menu mobile</button>
<!-- Padding responsive -->
<div class="p-4 md:p-8 lg:p-12"></div>
<!-- Container centré -->
<div class="container mx-auto px-4 md:px-6 lg:px-8"></div>
5. Dark Mode
// tailwind.config.js — activer le dark mode
module.exports = {
darkMode: 'class', // 'class' (toggle manuel) ou 'media' (système)
// ...
}
<!-- Avec darkMode: 'class' -->
<html class="dark"> <!-- Ajouter/retirer cette classe avec JS -->
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
<h1 class="text-gray-800 dark:text-white">Titre</h1>
<p class="text-gray-600 dark:text-gray-400">Texte secondaire</p>
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-4
bg-gray-50 dark:bg-gray-800">
Carte
</div>
</div>
<!-- Toggle JS -->
<button onclick="document.documentElement.classList.toggle('dark')">
🌙 Toggle
</button>
6. Hover, Focus & États
<!-- ── Pseudo-classes ── -->
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed">
Bouton
</button>
<!-- ── Group hover ── -->
<div class="group cursor-pointer">
<img class="group-hover:scale-105 transition-transform duration-300">
<h3 class="group-hover:text-blue-500 transition-colors">Titre</h3>
<p class="opacity-0 group-hover:opacity-100 transition-opacity">Visible au hover</p>
</div>
<!-- ── Peer (frère) ── -->
<input type="checkbox" class="peer hidden">
<label class="peer-checked:bg-blue-500 peer-checked:text-white ...">
Option
</label>
<!-- ── Transitions ── -->
<div class="transition-all duration-300 ease-in-out"></div>
<div class="transition-colors duration-200"></div>
<div class="transition-transform duration-500 ease-out"></div>
<!-- ── Transforms ── -->
<div class="hover:scale-105 hover:-translate-y-1 hover:rotate-3"></div>
7. Flex & Grid Tailwind
<!-- ── Flexbox ── -->
<div class="flex items-center justify-between gap-4 flex-wrap">
<span>Logo</span>
<nav class="flex gap-6 items-center">...</nav>
</div>
<!-- Centrage parfait -->
<div class="flex items-center justify-center min-h-screen"></div>
<!-- Colonne flex -->
<div class="flex flex-col h-full">
<div class="flex-1">Contenu (prend tout l'espace)</div>
<footer>Pied</footer>
</div>
<!-- ── CSS Grid ── -->
<!-- Colonnes fixes -->
<div class="grid grid-cols-3 gap-6"></div>
<div class="grid grid-cols-12 gap-4">
<div class="col-span-8">Main</div>
<div class="col-span-4">Sidebar</div>
</div>
<!-- Auto responsive -->
<div class="grid grid-cols-[repeat(auto-fill,minmax(280px,1fr))] gap-6"></div>
<!-- Layout page -->
<div class="grid grid-rows-[auto_1fr_auto] min-h-screen">
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
8. Composants custom avec @apply
/* Avec @apply dans votre CSS — extrait les classes en composant réutilisable */
@layer components {
.btn {
@apply inline-flex items-center gap-2 px-4 py-2
font-semibold rounded-lg transition-all duration-200
focus:outline-none focus:ring-2 focus:ring-offset-2;
}
.btn-primary {
@apply bg-blue-600 text-white hover:bg-blue-700
focus:ring-blue-500;
}
.btn-secondary {
@apply bg-gray-100 text-gray-900 hover:bg-gray-200
focus:ring-gray-400;
}
.card {
@apply bg-white dark:bg-gray-800
border border-gray-200 dark:border-gray-700
rounded-xl p-6 shadow-sm
hover:shadow-md transition-shadow;
}
.input {
@apply w-full px-4 py-2 rounded-lg border border-gray-300
bg-white focus:outline-none focus:ring-2 focus:ring-blue-500
focus:border-transparent placeholder-gray-400
dark:bg-gray-800 dark:border-gray-600 dark:text-white;
}
.badge {
@apply inline-flex items-center px-2.5 py-0.5
rounded-full text-xs font-semibold;
}
}
<!-- Utilisation -->
<button class="btn btn-primary">Enregistrer</button>
<div class="card">...</div>
<input class="input" type="text">
<span class="badge bg-green-100 text-green-800">Actif</span>
9. tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js,jsx,tsx,vue}'],
darkMode: 'class',
theme: {
// Remplacer complètement les valeurs par défaut
screens: {
sm: '640px', md: '768px', lg: '1024px', xl: '1280px',
},
// Étendre sans remplacer
extend: {
colors: {
brand: {
50: '#eff6ff',
500: '#3b82f6',
900: '#1e3a5f',
},
// Utiliser des valeurs CSS custom
primary: 'var(--color-primary)',
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['Fira Code', 'monospace'],
},
spacing: {
18: '4.5rem',
88: '22rem',
128: '32rem',
},
borderRadius: {
'4xl': '2rem',
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out',
'slide-up': 'slideUp 0.4s ease-out',
},
keyframes: {
fadeIn: { from: { opacity: '0' }, to: { opacity: '1' } },
slideUp: { from: { transform: 'translateY(16px)', opacity: '0' }, to: { transform: 'translateY(0)', opacity: '1' } },
},
},
},
plugins: [
require('@tailwindcss/forms'), // Reset et styles pour les formulaires
require('@tailwindcss/typography'), // Classes prose pour le contenu riche
require('@tailwindcss/aspect-ratio'), // Classes aspect-ratio
],
};
10. Tailwind vs Bootstrap — Comparaison
<!-- MÊME RÉSULTAT — deux approches différentes -->
<!-- Bootstrap 5 -->
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">Titre</h5>
<p class="card-text text-muted">Description</p>
<a href="#" class="btn btn-primary">Action</a>
</div>
</div>
<!-- Tailwind CSS -->
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6">
<h5 class="text-lg font-semibold text-gray-900 mb-2">Titre</h5>
<p class="text-gray-500 text-sm mb-4">Description</p>
<a href="#" class="inline-flex items-center px-4 py-2 bg-blue-600
hover:bg-blue-700 text-white text-sm font-medium
rounded-lg transition-colors">
Action
</a>
</div>
Quand choisir ?
Bootstrap : prototypage rapide, équipes non-CSS, applications internes.
Tailwind : design sur mesure, composants uniques, contrôle total, projets long terme.
Bootstrap : prototypage rapide, équipes non-CSS, applications internes.
Tailwind : design sur mesure, composants uniques, contrôle total, projets long terme.