Tailwind CSS v3
Framework CSS utility-first — composez des interfaces directement dans votre HTML avec des classes atomiques.
# 1. Installer Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
# 2. Créer le fichier de configuration
npx tailwindcss init
# 3. Avec PostCSS
npx tailwindcss init -p
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
// Fichiers à scanner pour les classes utilisées (tree-shaking)
content: [
'./src/**/*.{html,js,jsx,ts,tsx,vue}',
'./pages/**/*.{js,jsx,ts,tsx}',
'./components/**/*.{js,jsx,ts,tsx}',
'./index.html',
],
// Activation du dark mode par classe
darkMode: 'class',
theme: {
extend: {
// Étendre le thème sans écraser
colors: {
brand: {
50: '#f0f9ff',
500: '#0ea5e9',
900: '#0c4a6e',
},
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
},
},
plugins: [],
};
/* src/input.css — Directives Tailwind */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Vous pouvez ajouter vos propres styles ici */
@layer components {
.btn-primary {
@apply bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition-colors;
}
}
# Compiler (watch mode)
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch
# Build production (minifié)
npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify
Le CDN Play inclut toutes les classes Tailwind sans configuration. A n'utiliser qu'en développement ou prototypage — pas optimal pour la production.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Prototype Tailwind</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: { brand: '#0ea5e9' }
}
}
}
</script>
</head>
<body class="bg-gray-100 p-8">
<h1 class="text-3xl font-bold text-gray-900">Bonjour Tailwind !</h1>
</body>
</html>
<!-- Container centré avec padding auto -->
<div class="container mx-auto px-4">...</div>
<!-- Largeurs max -->
<div class="max-w-sm">max-width: 24rem</div>
<div class="max-w-md">max-width: 28rem</div>
<div class="max-w-lg">max-width: 32rem</div>
<div class="max-w-xl">max-width: 36rem</div>
<div class="max-w-2xl">max-width: 42rem</div>
<div class="max-w-4xl">max-width: 56rem</div>
<div class="max-w-screen-lg">max-width: 1024px</div>
<div class="max-w-prose">max-width: 65ch (lisibilité optimale)</div>
<!-- Largeurs en % -->
<div class="w-full">width: 100%</div>
<div class="w-1/2">width: 50%</div>
<div class="w-1/3">width: 33.33%</div>
<!-- Hauteurs -->
<div class="h-screen">height: 100vh</div>
<div class="min-h-screen">min-height: 100vh</div>
<div class="h-full">height: 100%</div>
<!-- Aspect ratio -->
<div class="aspect-video">16/9 (vidéo)</div>
<div class="aspect-square">1/1 (carré)</div>
<!-- Display -->
<div class="block">display: block</div>
<span class="inline-block">display: inline-block</span>
<div class="hidden">display: none</div>
<!-- Position -->
<div class="relative">
<div class="absolute top-0 right-0">Coin haut-droite</div>
<div class="absolute inset-0">Couvre tout le parent</div>
</div>
<div class="fixed top-0 left-0 right-0 z-50">Navbar fixe</div>
<div class="sticky top-0 z-10">Sticky sidebar</div>
<!-- Overflow -->
<div class="overflow-hidden">...</div>
<div class="overflow-auto">...</div>
<div class="overflow-x-auto">scroll horizontal</div>
<!-- Activer flex -->
<div class="flex">...</div>
<div class="inline-flex">...</div>
<!-- Direction -->
<div class="flex flex-row">Horizontal (défaut)</div>
<div class="flex flex-col">Vertical</div>
<div class="flex flex-row-reverse">Horizontal inversé</div>
<div class="flex flex-col-reverse">Vertical inversé</div>
<!-- Justify-content -->
<div class="flex justify-start">...</div>
<div class="flex justify-end">...</div>
<div class="flex justify-center">...</div>
<div class="flex justify-between">...</div>
<div class="flex justify-around">...</div>
<div class="flex justify-evenly">...</div>
<!-- Align-items -->
<div class="flex items-start">...</div>
<div class="flex items-end">...</div>
<div class="flex items-center">...</div>
<div class="flex items-stretch">...</div>
<div class="flex items-baseline">...</div>
<!-- Wrap -->
<div class="flex flex-wrap">...</div>
<div class="flex flex-nowrap">...</div>
<!-- Gap -->
<div class="flex gap-4">gap: 1rem</div>
<div class="flex gap-x-4 gap-y-2">gap-x et gap-y séparés</div>
<!-- Flex items -->
<div class="flex">
<div class="flex-1">Prend l'espace disponible</div>
<div class="flex-auto">Taille selon contenu + grandit</div>
<div class="flex-none">Taille fixe, ne grandit pas</div>
</div>
<!-- Grow / Shrink -->
<div class="grow">flex-grow: 1</div>
<div class="shrink-0">flex-shrink: 0</div>
<!-- Self-alignment -->
<div class="self-start">...</div>
<div class="self-center">...</div>
<div class="self-end">...</div>
<!-- Order -->
<div class="order-first">Premier</div>
<div class="order-last">Dernier</div>
<div class="order-2">2ème position</div>
<!-- Centrage parfait (pattern courant) -->
<div class="flex items-center justify-center h-screen">
<p>Centré horizontalement et verticalement</p>
</div>
<!-- Activer grid -->
<div class="grid">...</div>
<!-- Colonnes -->
<div class="grid grid-cols-1">1 colonne</div>
<div class="grid grid-cols-2">2 colonnes</div>
<div class="grid grid-cols-3">3 colonnes</div>
<div class="grid grid-cols-4">4 colonnes</div>
<div class="grid grid-cols-6">6 colonnes</div>
<div class="grid grid-cols-12">12 colonnes</div>
<!-- Gap -->
<div class="grid grid-cols-3 gap-4">...</div>
<div class="grid grid-cols-3 gap-x-6 gap-y-4">...</div>
<!-- Colspan -->
<div class="grid grid-cols-6">
<div class="col-span-2">Occupe 2 colonnes</div>
<div class="col-span-4">Occupe 4 colonnes</div>
<div class="col-span-full">Pleine largeur</div>
</div>
<!-- Lignes -->
<div class="grid grid-rows-3">...</div>
<div class="row-span-2">Occupe 2 lignes</div>
<!-- Place-items (alignement dans les cellules) -->
<div class="grid place-items-center h-48">
<p>Centré dans la grille</p>
</div>
<!-- Grille responsive (pattern courant) -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
<div class="bg-white rounded-lg p-4 shadow">Carte 1</div>
<div class="bg-white rounded-lg p-4 shadow">Carte 2</div>
<div class="bg-white rounded-lg p-4 shadow">Carte 3</div>
<div class="bg-white rounded-lg p-4 shadow">Carte 4</div>
</div>
Tailwind utilise une échelle de 4px : 1 = 4px, 2 = 8px, 4 = 16px, 8 = 32px, 16 = 64px…
<!-- Padding -->
<div class="p-4">padding: 1rem (16px) tous côtés</div>
<div class="px-4">padding left + right</div>
<div class="py-4">padding top + bottom</div>
<div class="pt-4">padding-top: 1rem</div>
<div class="pb-8">padding-bottom: 2rem</div>
<div class="pl-2 pr-6">left: 0.5rem, right: 1.5rem</div>
<!-- Margin -->
<div class="m-4">margin: 1rem tous côtés</div>
<div class="mx-auto">centrage horizontal</div>
<div class="mt-4">margin-top: 1rem</div>
<div class="mb-8">margin-bottom: 2rem</div>
<div class="my-6">margin top + bottom: 1.5rem</div>
<!-- Space between (espacement entre enfants) -->
<div class="flex space-x-4"> <!-- margin entre enfants horizontaux -->
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<div class="flex flex-col space-y-4"> <!-- margin entre enfants verticaux -->
<div>Item 1</div>
<div>Item 2</div>
</div>
<!-- Largeurs -->
<div class="w-4">width: 1rem</div>
<div class="w-8">width: 2rem</div>
<div class="w-16">width: 4rem</div>
<div class="w-32">width: 8rem</div>
<div class="w-48">width: 12rem</div>
<div class="w-64">width: 16rem</div>
<div class="w-full">width: 100%</div>
<div class="w-screen">width: 100vw</div>
<!-- Hauteurs -->
<div class="h-4">height: 1rem</div>
<div class="h-16">height: 4rem</div>
<div class="h-full">height: 100%</div>
<div class="h-screen">height: 100vh</div>
<!-- Tailles de police -->
<p class="text-xs">xs — 0.75rem</p>
<p class="text-sm">sm — 0.875rem</p>
<p class="text-base">base — 1rem (défaut)</p>
<p class="text-lg">lg — 1.125rem</p>
<p class="text-xl">xl — 1.25rem</p>
<p class="text-2xl">2xl — 1.5rem</p>
<p class="text-3xl">3xl — 1.875rem</p>
<p class="text-4xl">4xl — 2.25rem</p>
<p class="text-5xl">5xl — 3rem</p>
<p class="text-6xl">6xl — 3.75rem</p>
<!-- Graisse de police -->
<p class="font-thin">Thin (100)</p>
<p class="font-light">Light (300)</p>
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semi-gras (600)</p>
<p class="font-bold">Gras (700)</p>
<p class="font-extrabold">Extra-gras (800)</p>
<p class="font-black">Black (900)</p>
<!-- Style -->
<p class="italic">Italique</p>
<p class="not-italic">Normal</p>
<!-- Espacement des lettres -->
<p class="tracking-tight">Lettres serrées</p>
<p class="tracking-normal">Normal</p>
<p class="tracking-wide">Lettres espacées</p>
<p class="tracking-widest">Très espacées</p>
<!-- Interlignage -->
<p class="leading-tight">Lignes serrées</p>
<p class="leading-normal">Normal</p>
<p class="leading-relaxed">Détendu</p>
<p class="leading-loose">Large</p>
<!-- Alignement -->
<p class="text-left">Gauche</p>
<p class="text-center">Centré</p>
<p class="text-right">Droite</p>
<p class="text-justify">Justifié</p>
<!-- Transformation -->
<p class="uppercase">TOUT EN MAJUSCULES</p>
<p class="lowercase">tout en minuscules</p>
<p class="capitalize">Première Lettre En Majuscule</p>
<!-- Décoration -->
<a class="underline">Souligné</a>
<a class="no-underline">Sans soulignement</a>
<!-- Troncature -->
<p class="truncate">Texte trop long tronqué...</p>
<p class="line-clamp-2">Texte limité à 2 lignes puis tronqué avec ellipsis...</p>
<!-- Listes -->
<ul class="list-disc list-inside">
<li>Item avec puce</li>
</ul>
<ul class="list-none">
<li>Item sans puce</li>
</ul>
Tailwind fournit une palette complète avec des teintes de 50 (très clair) à 950 (très foncé). Familles disponibles : slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose.
<!-- Couleur de texte -->
<p class="text-slate-900">Presque noir</p>
<p class="text-gray-600">Gris moyen</p>
<p class="text-blue-500">Bleu standard</p>
<p class="text-red-600">Rouge</p>
<p class="text-green-500">Vert</p>
<p class="text-yellow-400">Jaune</p>
<p class="text-white">Blanc</p>
<!-- Fond -->
<div class="bg-white">Fond blanc</div>
<div class="bg-gray-100">Fond gris très clair</div>
<div class="bg-gray-900">Fond sombre</div>
<div class="bg-blue-500">Fond bleu</div>
<div class="bg-emerald-400">Fond vert émeraude</div>
<!-- Opacité des couleurs (syntaxe /) -->
<div class="bg-blue-500/50">Fond bleu à 50% d'opacité</div>
<div class="bg-black/75">Fond noir à 75% d'opacité</div>
<p class="text-black/75">Texte noir à 75%</p>
<!-- Dégradés -->
<div class="bg-gradient-to-r from-blue-500 to-purple-600">Dégradé gauche→droite</div>
<div class="bg-gradient-to-br from-sky-400 via-blue-500 to-indigo-600">Dégradé diagonal avec via</div>
<div class="bg-gradient-to-b from-transparent to-black/50">Overlay sombre en bas</div>
// Couleurs personnalisées dans tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
light: '#60a5fa',
DEFAULT: '#3b82f6',
dark: '#1d4ed8',
},
// Usage : text-brand, bg-brand-light, bg-brand-dark
},
},
},
};
<!-- Bordures -->
<div class="border">Bordure 1px</div>
<div class="border-2">Bordure 2px</div>
<div class="border-4">Bordure 4px</div>
<div class="border-0">Sans bordure</div>
<!-- Côtés spécifiques -->
<div class="border-t">Bordure top seulement</div>
<div class="border-b">Bordure bottom seulement</div>
<div class="border-l">Bordure left seulement</div>
<div class="border-r">Bordure right seulement</div>
<!-- Couleurs de bordure -->
<div class="border border-gray-200">Bordure grise claire</div>
<div class="border-2 border-blue-500">Bordure bleue</div>
<div class="border border-red-300">Bordure rouge</div>
<!-- Border-radius -->
<div class="rounded">0.25rem</div>
<div class="rounded-md">0.375rem</div>
<div class="rounded-lg">0.5rem</div>
<div class="rounded-xl">0.75rem</div>
<div class="rounded-2xl">1rem</div>
<div class="rounded-3xl">1.5rem</div>
<div class="rounded-full">9999px — cercle ou pilule</div>
<!-- Ring (outline/focus ring) -->
<input class="ring-2 ring-blue-500">Avec ring bleu</input>
<input class="focus:ring-2 focus:ring-blue-500 focus:outline-none">Focus ring</input>
<div class="ring-1 ring-gray-200 ring-offset-2">Avec offset</div>
<!-- Ombres -->
<div class="shadow-sm">Ombre légère</div>
<div class="shadow">Ombre standard</div>
<div class="shadow-md">Ombre moyenne</div>
<div class="shadow-lg">Ombre large</div>
<div class="shadow-xl">Ombre très large</div>
<div class="shadow-2xl">Ombre maximale</div>
<div class="shadow-none">Sans ombre</div>
<!-- Ombre colorée -->
<button class="shadow-lg shadow-blue-500/50">Ombre bleue</button>
<!-- Propriétés à transitionner -->
<div class="transition">Toutes les propriétés communes</div>
<div class="transition-all">Toutes les propriétés</div>
<div class="transition-colors">Couleur / fond seulement</div>
<div class="transition-transform">Transform seulement</div>
<div class="transition-opacity">Opacité seulement</div>
<!-- Durée -->
<div class="transition duration-150">150ms</div>
<div class="transition duration-200">200ms</div>
<div class="transition duration-300">300ms</div>
<div class="transition duration-500">500ms</div>
<div class="transition duration-700">700ms</div>
<!-- Timing functions -->
<div class="transition ease-linear">Linéaire</div>
<div class="transition ease-in">Accélère</div>
<div class="transition ease-out">Décélère</div>
<div class="transition ease-in-out">Les deux</div>
<!-- Délai -->
<div class="transition delay-150">Délai 150ms</div>
<!-- Bouton avec transition complète -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg
transition-all duration-200 ease-in-out
hover:bg-blue-600 hover:shadow-lg hover:scale-105
active:scale-95">
Cliquez-moi
</button>
<!-- Animations prédéfinies -->
<div class="animate-spin">Rotation continue (loader)</div>
<div class="animate-ping">Effet radar / notification</div>
<div class="animate-pulse">Pulsation (skeleton loading)</div>
<div class="animate-bounce">Rebond (scroll indicator)</div>
<!-- Loader spinner -->
<div class="animate-spin h-8 w-8 border-4 border-gray-300
border-t-blue-500 rounded-full"></div>
<!-- Skeleton loading -->
<div class="animate-pulse space-y-3">
<div class="h-4 bg-gray-200 rounded w-3/4"></div>
<div class="h-4 bg-gray-200 rounded"></div>
<div class="h-4 bg-gray-200 rounded w-5/6"></div>
</div>
<!-- Notification dot -->
<span class="relative flex h-3 w-3">
<span class="animate-ping absolute inline-flex h-full w-full
rounded-full bg-sky-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-sky-500"></span>
</span>
<!-- Transforms au hover -->
<div class="hover:scale-105 transition-transform duration-200">Zoom au hover</div>
<div class="hover:rotate-3 transition-transform">Rotation au hover</div>
<div class="hover:-translate-y-1 transition-transform">Remonte au hover</div>
Tailwind est mobile first : les classes sans préfixe s'appliquent à tous les écrans, les préfixées écrasent à partir du breakpoint indiqué.
| Préfixe | Min-width | Appareils |
|---|---|---|
| (aucun) | 0px | Tous écrans (mobile) |
sm: | 640px | Téléphones paysage |
md: | 768px | Tablettes |
lg: | 1024px | Petits desktops |
xl: | 1280px | Desktops |
2xl: | 1536px | Grands écrans |
<!-- Texte responsive -->
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
Titre responsive
</h1>
<!-- Affichage conditionnel -->
<div class="hidden md:block">Visible seulement sur tablette+</div>
<div class="block md:hidden">Visible seulement sur mobile</div>
<!-- Layout responsive -->
<div class="flex flex-col lg:flex-row gap-6">
<aside class="w-full lg:w-64 shrink-0">Sidebar</aside>
<main class="flex-1">Contenu principal</main>
</div>
<!-- Grille de cartes responsive -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
<div class="bg-white rounded-xl shadow-md overflow-hidden">
<img src="img.jpg" class="w-full h-48 object-cover" alt="Card image" />
<div class="p-4">
<h3 class="font-semibold text-gray-900 truncate">Titre de la carte</h3>
<p class="text-sm text-gray-500 mt-1 line-clamp-2">Description courte.</p>
<button class="mt-4 w-full bg-blue-500 text-white py-2 rounded-lg
hover:bg-blue-600 transition-colors text-sm font-medium">
Voir plus
</button>
</div>
</div>
</div>
<!-- Padding responsive -->
<div class="px-4 sm:px-6 md:px-8 lg:px-12">
Padding qui grandit avec l'écran
</div>
dark:Activez darkMode: 'class' dans la config, puis ajoutez la classe dark sur l'élément <html> pour activer le mode sombre.
// tailwind.config.js
module.exports = {
darkMode: 'class', // active le dark mode via la classe .dark sur <html>
// ...
};
// Toggle dark mode en JavaScript
function toggleDarkMode() {
document.documentElement.classList.toggle('dark');
}
// Persistance avec localStorage
function initDarkMode() {
if (
localStorage.getItem('darkMode') === 'true' ||
(!localStorage.getItem('darkMode') &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark');
}
}
function toggleDarkMode() {
const isDark = document.documentElement.classList.toggle('dark');
localStorage.setItem('darkMode', isDark);
}
<!-- Classes dark: -->
<body class="bg-white dark:bg-gray-900">
<h1 class="text-gray-900 dark:text-white">Titre</h1>
<p class="text-gray-600 dark:text-gray-400">Paragraphe</p>
<!-- Card en dark mode -->
<div class="bg-white dark:bg-gray-800 border border-gray-200
dark:border-gray-700 rounded-xl p-6 shadow-sm">
<h2 class="font-semibold text-gray-900 dark:text-white">Carte dark mode</h2>
<p class="text-gray-500 dark:text-gray-400 mt-2">Description.</p>
<button class="mt-4 bg-blue-500 dark:bg-blue-600 text-white
px-4 py-2 rounded-lg hover:bg-blue-600 dark:hover:bg-blue-700
transition-colors">
Action
</button>
</div>
<!-- Input dark mode -->
<input class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white
border border-gray-300 dark:border-gray-600 rounded-lg px-4 py-2
focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400
focus:outline-none placeholder:text-gray-400 dark:placeholder:text-gray-500"
placeholder="Rechercher..." />
<!-- Toggle button -->
<button onclick="toggleDarkMode()"
class="p-2 rounded-lg bg-gray-100 dark:bg-gray-700
text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600
transition-colors">
☀️ / 🌙
</button>
</body>
<!-- Hover -->
<button class="bg-blue-500 hover:bg-blue-600 hover:shadow-lg transition-all">
Survol
</button>
<!-- Focus -->
<input class="border border-gray-300 focus:border-blue-500
focus:ring-2 focus:ring-blue-500/30 focus:outline-none rounded-lg px-4 py-2"
placeholder="Focus ring" />
<!-- Active -->
<button class="bg-blue-500 hover:bg-blue-600 active:scale-95
active:bg-blue-700 transition-all">
Cliquez
</button>
<!-- Disabled -->
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg
disabled:opacity-50 disabled:cursor-not-allowed" disabled>
Désactivé
</button>
<!-- Group hover (parent contrôle les enfants) -->
<div class="group bg-white hover:bg-blue-500 rounded-xl p-6 transition-colors cursor-pointer">
<h3 class="text-gray-900 group-hover:text-white font-semibold transition-colors">
Titre de la carte
</h3>
<p class="text-gray-500 group-hover:text-blue-100 text-sm mt-1 transition-colors">
La couleur change au hover du parent.
</p>
<svg class="text-blue-500 group-hover:text-white mt-4 transition-colors w-5 h-5">
...
</svg>
</div>
<!-- Peer (input contrôle son voisin) -->
<div class="relative">
<input class="peer border rounded-lg px-4 py-2 focus:outline-none"
placeholder=" " id="email" />
<label for="email"
class="absolute left-4 top-2.5 text-gray-400 text-sm
peer-focus:-top-2 peer-focus:text-xs peer-focus:text-blue-500
transition-all">
Email
</label>
</div>
<!-- First / Last / Odd / Even -->
<ul>
<li class="py-2 first:pt-0 last:pb-0 odd:bg-gray-50 even:bg-white
border-b last:border-0">Item</li>
</ul>
<!-- Placeholder -->
<input class="placeholder:text-gray-400 placeholder:italic" placeholder="Texte gris italique" />
<!-- Selection -->
<p class="selection:bg-blue-500 selection:text-white">
Sélectionnez ce texte pour voir l'effet.
</p>
<button class="inline-flex items-center gap-2
bg-blue-600 hover:bg-blue-700 active:bg-blue-800
text-white text-sm font-semibold
px-5 py-2.5 rounded-lg
shadow-sm hover:shadow-md
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
active:scale-95
disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-150">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
Confirmer
</button>
<div class="bg-white dark:bg-gray-800 rounded-2xl shadow-md overflow-hidden
hover:shadow-xl transition-shadow duration-300 max-w-sm">
<!-- Image -->
<div class="relative overflow-hidden h-48">
<img src="image.jpg" alt="Article"
class="w-full h-full object-cover hover:scale-105 transition-transform duration-500" />
<span class="absolute top-3 right-3 bg-blue-500 text-white
text-xs font-bold px-2 py-1 rounded-full">
Nouveau
</span>
</div>
<!-- Contenu -->
<div class="p-5">
<div class="flex items-center gap-2 mb-3">
<span class="text-xs text-blue-600 dark:text-blue-400 font-semibold uppercase tracking-wide">
Technologie
</span>
<span class="text-xs text-gray-400">• 5 min de lecture</span>
</div>
<h3 class="text-lg font-bold text-gray-900 dark:text-white line-clamp-2 mb-2">
Titre de l'article intéressant
</h3>
<p class="text-gray-500 dark:text-gray-400 text-sm line-clamp-3 mb-4">
Description courte de l'article qui peut faire plusieurs lignes mais sera
tronquée après trois lignes.
</p>
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white text-sm
font-medium py-2 rounded-lg transition-colors">
Lire l'article
</button>
</div>
</div>
<!-- Badges -->
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs
font-medium bg-blue-100 text-blue-800">
Nouveau
</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs
font-medium bg-green-100 text-green-800">
Actif
</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs
font-medium bg-red-100 text-red-800">
Erreur
</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs
font-medium bg-yellow-100 text-yellow-800">
En attente
</span>
<!-- Alert/Notification -->
<div class="flex items-start gap-4 p-4 bg-green-50 border border-green-200
rounded-xl dark:bg-green-900/20 dark:border-green-800">
<div class="flex-shrink-0 w-5 h-5 text-green-500 mt-0.5">
<svg fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
</svg>
</div>
<div class="flex-1">
<h4 class="text-sm font-semibold text-green-800 dark:text-green-300">
Succès !
</h4>
<p class="text-sm text-green-700 dark:text-green-400 mt-1">
Votre opération a été réalisée avec succès.
</p>
</div>
<button class="text-green-400 hover:text-green-600 transition-colors">
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
</div>
<div class="space-y-4">
<!-- Input classique -->
<div>
<label for="nom" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Nom complet
</label>
<input id="nom" type="text"
class="w-full bg-white dark:bg-gray-800
text-gray-900 dark:text-white
border border-gray-300 dark:border-gray-600
rounded-lg px-4 py-2.5 text-sm
placeholder:text-gray-400
focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500
transition-colors"
placeholder="Jean Dupont" />
</div>
<!-- Input avec icône -->
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</div>
<input type="email"
class="w-full pl-10 pr-4 py-2.5 border border-gray-300 dark:border-gray-600
rounded-lg text-sm bg-white dark:bg-gray-800
focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 focus:outline-none
transition-colors"
placeholder="email@exemple.com" />
</div>
</div>
<nav class="bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800
sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<!-- Logo -->
<a href="#" class="flex items-center gap-2 font-bold text-xl text-gray-900 dark:text-white">
<span class="text-blue-500">My</span>App
</a>
<!-- Menu desktop -->
<ul class="hidden md:flex items-center gap-6 text-sm">
<li><a href="#" class="text-gray-700 dark:text-gray-300 hover:text-blue-500 transition-colors font-medium">Accueil</a></li>
<li><a href="#" class="text-gray-700 dark:text-gray-300 hover:text-blue-500 transition-colors">Fonctionnalités</a></li>
<li><a href="#" class="text-gray-700 dark:text-gray-300 hover:text-blue-500 transition-colors">Tarifs</a></li>
</ul>
<!-- Actions desktop -->
<div class="hidden md:flex items-center gap-3">
<a href="#" class="text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white transition-colors">
Connexion
</a>
<a href="#" class="bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium
px-4 py-2 rounded-lg transition-colors">
S'inscrire
</a>
</div>
<!-- Bouton hamburger mobile -->
<button id="menuBtn" class="md:hidden p-2 rounded-lg text-gray-600 dark:text-gray-400
hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
onclick="document.getElementById('mobileMenu').classList.toggle('hidden')">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
</div>
<!-- Menu mobile -->
<div id="mobileMenu" class="hidden md:hidden border-t border-gray-200 dark:border-gray-800">
<div class="px-4 py-4 space-y-3">
<a href="#" class="block text-gray-700 dark:text-gray-300 hover:text-blue-500">Accueil</a>
<a href="#" class="block text-gray-700 dark:text-gray-300 hover:text-blue-500">Fonctionnalités</a>
<a href="#" class="block text-gray-700 dark:text-gray-300 hover:text-blue-500">Tarifs</a>
<hr class="border-gray-200 dark:border-gray-700" />
<a href="#" class="block bg-blue-600 text-white text-center py-2 rounded-lg">S'inscrire</a>
</div>
</div>
</nav>
<!-- Avatar simple -->
<img src="avatar.jpg" alt="Alice"
class="w-10 h-10 rounded-full object-cover ring-2 ring-blue-500 ring-offset-2" />
<!-- Avatar avec initiales -->
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center
text-white font-semibold text-sm">
AD
</div>
<!-- Avatar avec indicateur de statut -->
<div class="relative inline-flex">
<img src="avatar.jpg" alt="Alice"
class="w-12 h-12 rounded-full object-cover" />
<!-- Point vert = en ligne -->
<span class="absolute bottom-0 right-0 block h-3 w-3 rounded-full
bg-green-400 ring-2 ring-white dark:ring-gray-900"></span>
</div>
<!-- Groupe d'avatars empilés -->
<div class="flex -space-x-3">
<img src="a1.jpg" alt="Alice"
class="w-9 h-9 rounded-full ring-2 ring-white dark:ring-gray-900 object-cover" />
<img src="a2.jpg" alt="Bob"
class="w-9 h-9 rounded-full ring-2 ring-white dark:ring-gray-900 object-cover" />
<img src="a3.jpg" alt="Carol"
class="w-9 h-9 rounded-full ring-2 ring-white dark:ring-gray-900 object-cover" />
<div class="w-9 h-9 rounded-full ring-2 ring-white dark:ring-gray-900
bg-gray-200 dark:bg-gray-700 flex items-center justify-center
text-xs font-medium text-gray-600 dark:text-gray-300">
+5
</div>
</div>
Aucun résultat pour votre recherche.