Tailwind CSS — les bases
Slides
Deck 7 — Tailwind CSS (PDF)PDF
Objectif : comprendre ce qu'est une classe utilitaire, installer Tailwind CSS v4 dans ton projet Vue, et savoir styler un bouton, un champ, une mise en page et un texte sans écrire une seule ligne de CSS.
1. C'est quoi, « utility-first » ?
Tailwind CSS est un framework CSS utility-first : au lieu d'écrire des règles CSS et d'inventer des noms de classes, tu assembles des petites classes qui font une chose chacune. px-4, c'est du padding horizontal. rounded-lg, c'est des coins arrondis. Tu composes.
En CSS classique, tu écris d'abord la règle :
.bouton-primaire {
background-color: #1c1a17;
color: #f4efe6;
padding: 10px 20px;
border-radius: 6px;
}
Puis tu l'utilises :
<button class="bouton-primaire">Clique-moi</button>
Avec Tailwind, tout tient dans le balisage :
<button class="bg-zinc-900 text-stone-50 px-5 py-2.5 rounded-md">
Clique-moi
</button>
Pas de fichier CSS à maintenir, pas de nom de classe à inventer, pas de « c'est quoi déjà, .btn-primary-2-final ? ». Le style est là où il s'applique.
Note
Ça paraît verbeux au début. C'est normal. Après deux séances, tu liras une ligne de classes plus vite que tu ne retrouverais la règle CSS correspondante dans un fichier de 800 lignes.
Ce que tu vas apprendre dans ce chapitre :
- installer Tailwind v4 dans ton projet Vue ;
- styler les briques de base : boutons, champs, mises en page, typographie, couleurs ;
- rendre tout ça responsive et accessible.
2. Installation dans le projet Vue
On installe Tailwind v4. C'est important : la v4 n'a plus de fichier tailwind.config.js et beaucoup de tutos que tu trouveras en ligne parlent encore de la v3. Si un tuto te demande de créer un tailwind.config.js ou de toucher à PostCSS, c'est de la v3, passe ton chemin.
Tu pars de ton projet Vue déjà créé et nettoyé (App.vue ne contient plus qu'un <h1>).
Étape 1 — Installer les paquets
Dans le terminal, à la racine de ton projet :
npm install tailwindcss @tailwindcss/vite
Étape 2 — Brancher le plugin dans Vite
Ouvre vite.config.js. Ajoute l'import en haut et tailwindcss() dans le tableau plugins — vue() et vueDevTools() y sont déjà.
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
vue(),
vueDevTools(),
tailwindcss(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
})
Tu n'ajoutes que deux lignes : l'import de tailwindcss et l'appel tailwindcss() dans plugins. Ne supprime rien d'autre : vueDevTools() et le raccourci @ du bloc resolve étaient déjà là.
Étape 3 — Importer Tailwind dans le CSS
Ouvre src/assets/main.css et remplace tout son contenu par cette ligne :
@import "tailwindcss";
C'est tout. Une ligne. Vérifie juste que src/main.js importe bien ce fichier (import './assets/main.css') — c'est le cas par défaut.
Étape 4 — Relancer le serveur
Le plugin Vite vient d'être ajouté : il faut redémarrer le serveur pour qu'il soit pris en compte. Dans le terminal, Ctrl + C pour arrêter (oui, Ctrl aussi sur Mac, pas Cmd), puis :
npm run dev
Étape 5 — Tester que ça marche
Ouvre src/App.vue et remplace son contenu par ceci :
<script setup>
// Rien ici pour l'instant.
</script>
<template>
<main class="min-h-screen bg-stone-100 flex items-center justify-center p-8">
<div class="max-w-md border-2 border-zinc-900 bg-white p-8">
<p class="text-xs uppercase tracking-widest text-zinc-500">Test</p>
<h1 class="mt-2 text-4xl font-bold text-zinc-900">
Tailwind est branché.
</h1>
<p class="mt-4 text-zinc-600">
Fond crème, cadre noir, texte net. Si tu vois ça, on peut travailler.
</p>
</div>
</main>
</template>

Sauvegarde, retourne dans le navigateur. Tu dois voir un cadre noir centré sur un fond crème. Si tu vois du texte brut non stylé, c'est que Tailwind n'est pas branché : relis les étapes 2 et 3, et regarde les erreurs dans le terminal.
Astuce
VS Code : vérifie que l'extension Tailwind CSS IntelliSense s'active. Place ton curseur dans un attribut class, tape bg- et regarde : une liste de classes doit apparaître, avec un carré de couleur en face de chacune. Si rien ne s'affiche, ferme et rouvre le dossier du projet dans VS Code. Cette autocomplétion, c'est ton meilleur outil d'apprentissage : elle te montre ce qui existe.
3. Les bases
3.1 Boutons
Un bouton, c'est une couleur de fond, du padding, un texte lisible et une réaction au survol. Trois directions très différentes, avec les mêmes briques :
<button class="bg-zinc-900 text-stone-50 px-5 py-2.5 rounded-md hover:bg-zinc-700 transition">
Sobre
</button>
<button class="border-4 border-zinc-900 bg-amber-300 text-zinc-900 px-6 py-3 uppercase font-extrabold tracking-wide shadow-[4px_4px_0_0_#18181b] hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[6px_6px_0_0_#18181b] transition">
Brutaliste
</button>
<button class="border border-zinc-300 bg-white text-zinc-800 px-6 py-3 font-serif text-lg hover:border-zinc-900 transition">
Éditorial
</button>

Note
L'ombre décalée du bouton brutaliste n'existe pas comme classe toute faite. On l'écrit en valeur arbitraire, entre crochets : shadow-[4px_4px_0_0_#18181b]. Les espaces de la valeur CSS deviennent des _. C'est la porte de sortie de Tailwind quand une classe manque — à utiliser avec parcimonie.
| Classe | Utilité | Exemple |
|---|---|---|
bg-{couleur} |
Couleur de fond | bg-zinc-900 |
text-{couleur} |
Couleur du texte | text-stone-50 |
px-{n}, py-{n} |
Padding horizontal / vertical | px-4 py-2 |
rounded |
Coins arrondis | rounded-md, rounded-full, rounded-none |
border |
Bordure | border-2 border-zinc-900 |
hover: |
Style au survol | hover:bg-zinc-700 |
shadow |
Ombre portée | shadow-sm, shadow-lg |
transition |
Animer le changement | transition |
Attention
En Tailwind v4, l'échelle des ombres a bougé : l'ancien shadow-sm de la v3 s'appelle maintenant shadow-xs, et l'ancien shadow tout court s'appelle shadow-sm. Si un exemple trouvé en ligne te donne une ombre plus forte que prévu, c'est souvent ça.
3.2 Champs de formulaire
<input
class="border border-zinc-300 px-3 py-2 rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-900"
placeholder="Nom complet"
>
<input
class="border-4 border-zinc-900 bg-white px-4 py-3 text-lg font-bold placeholder:text-zinc-400 focus-visible:bg-amber-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-900"
placeholder="TON NOM"
>

| Classe | Utilité | Exemple |
|---|---|---|
border |
Bordure | border border-zinc-300 |
rounded |
Coins arrondis | rounded-md |
px-{n}, py-{n} |
Padding intérieur | px-4 py-2 |
placeholder: |
Style du texte d'exemple | placeholder:text-zinc-400 |
focus-visible: |
Apparence au focus clavier | focus-visible:outline-2 |
w-full |
Largeur totale du parent | w-full |
3.3 Mise en page : Flexbox et Grid
Centrer un bloc avec Flexbox :
<div class="flex items-center justify-center h-48 bg-stone-100">
<div class="bg-zinc-900 text-stone-50 p-4">Je suis centré.</div>
</div>
Une grille de trois colonnes égales :
<div class="grid grid-cols-3 gap-4">
<div class="bg-emerald-200 p-4">Bloc 1</div>
<div class="bg-emerald-300 p-4">Bloc 2</div>
<div class="bg-emerald-400 p-4">Bloc 3</div>
</div>

| Classe | Utilité | Exemple |
|---|---|---|
flex |
Conteneur Flexbox | flex |
items-center |
Alignement vertical (en flex-row) | items-center |
justify-between |
Répartition horizontale | justify-center, justify-between |
flex-col |
Empiler verticalement | flex-col |
grid, grid-cols-{n} |
Créer une grille | grid grid-cols-3 |
gap-{n} |
Espace entre les éléments | gap-4 (1 rem) |
3.4 Typographie
<h1 class="text-4xl font-bold tracking-tight text-zinc-900">Titre principal</h1>
<p class="mt-3 text-zinc-600 leading-relaxed">Un paragraphe confortable à lire.</p>
<p class="font-mono text-sm uppercase tracking-widest text-zinc-500">Étiquette</p>

| Classe | Utilité | Exemple |
|---|---|---|
text-{taille} |
Taille du texte | text-sm, text-xl, text-4xl |
font-{poids} |
Graisse | font-medium, font-bold, font-black |
font-{famille} |
Famille | font-sans, font-serif, font-mono |
leading-{n} |
Hauteur de ligne | leading-relaxed, leading-tight |
tracking-{n} |
Interlettrage | tracking-tight, tracking-widest |
uppercase |
Tout en majuscules | uppercase |
3.5 Couleurs et arrière-plans
<div class="bg-red-600 text-white p-4">Fond rouge, texte blanc</div>
<div class="bg-zinc-900 text-amber-300 p-4">Contraste franc</div>
<div class="bg-linear-to-b from-stone-100 to-stone-300 text-zinc-900 p-4">Dégradé discret</div>

| Classe | Utilité | Exemple |
|---|---|---|
bg-{couleur} |
Couleur de fond | bg-amber-300 |
text-{couleur} |
Couleur du texte | text-zinc-900 |
bg-linear-to-{dir} |
Dégradé linéaire | bg-linear-to-r, bg-linear-to-b |
from-, to- |
Bornes du dégradé | from-stone-100 to-stone-300 |
Attention
En Tailwind v4, le dégradé s'écrit bg-linear-to-r, pas bg-gradient-to-r (v3). Si tu copies un exemple qui ne produit aucun dégradé, vérifie d'abord ça.
Et rappelle-toi le chapitre sur le slop : un dégradé violet-rose sur fond sombre, ce n'est pas un style, c'est le réglage par défaut de tout le monde. Un aplat franc dit plus de choses.
4. Responsive et variantes d'état
4.1 Mobile first
Une classe sans préfixe s'applique partout. Un préfixe comme md: s'applique à partir de cette largeur. Donc : tu écris d'abord le style mobile, puis tu corriges pour les grands écrans.
<div class="flex flex-col md:flex-row gap-4">
<div class="bg-blue-200 p-4">Bloc 1</div>
<div class="bg-blue-300 p-4">Bloc 2</div>
<div class="bg-blue-400 p-4">Bloc 3</div>
</div>


Empilés sur mobile grâce à flex-col, côte à côte dès 768 px grâce à md:flex-row.
| Préfixe | Écrans | Largeur minimale |
|---|---|---|
| aucun | mobile | 0 px |
sm: |
grands mobiles | 640 px |
md: |
tablettes | 768 px |
lg: |
ordinateurs | 1024 px |
xl: |
grands écrans | 1280 px |
2xl: |
très grands écrans | 1536 px |
<p class="text-base md:text-lg lg:text-xl">
Texte qui grossit avec l'écran.
</p>
4.2 Variantes d'état
Même principe : un préfixe devant la classe.
<button class="bg-emerald-600 text-white px-5 py-2.5 rounded-md hover:bg-emerald-700 active:scale-95 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-emerald-700 transition">
Envoyer
</button>
<button class="bg-zinc-200 text-zinc-500 px-5 py-2.5 rounded-md disabled:cursor-not-allowed disabled:opacity-60" disabled>
Indisponible
</button>

| Variante | Utilité | Exemple |
|---|---|---|
hover: |
Au survol de la souris | hover:bg-zinc-700 |
focus: |
Au focus (clic ou clavier) | focus:border-zinc-900 |
focus-visible: |
Au focus clavier uniquement | focus-visible:outline-2 |
active: |
Pendant le clic | active:scale-95 |
disabled: |
Élément désactivé | disabled:opacity-60 |
Attention
Accessibilité : ne supprime jamais le focus sans le remplacer.
Beaucoup d'exemples trouvés en ligne mettent outline-none (ou outline-hidden en v4) sur les boutons et les champs « parce que le contour bleu du navigateur est moche ». Résultat : une personne qui navigue au clavier ne sait plus où elle est dans la page. C'est éliminatoire.
Deux règles, valables pour tous tes exercices :
- Focus visible obligatoire. Si tu enlèves le contour par défaut, tu en remets un :
focus-visible:ring-2 focus-visible:ring-zinc-900oufocus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-900. Teste avec la touche[TAB]: tu dois voir où tu es, à chaque étape. - Contraste suffisant. Un texte doit ressortir nettement sur son fond (ratio 4,5:1 minimum pour du texte courant).
text-zinc-400surbg-white, c'est joli sur ton écran neuf et illisible partout ailleurs. Dans le doute, descends d'un ou deux crans :text-zinc-600,text-zinc-700.
Attention aussi : en v4, ring tout seul fait 1 px (contre 3 px en v3). Écris ring-2 si tu veux un anneau franc.
4.3 Combiner les deux
Ça se cumule, dans l'ordre responsive puis état :
<button class="bg-red-600 text-white px-4 py-2 md:hover:bg-red-800 transition">
Survol renforcé sur grand écran
</button>
Récap
- Tailwind = des classes qui font une chose chacune, assemblées dans le
class. - Installation v4 :
npm install tailwindcss @tailwindcss/vite, plugin dansvite.config.js,@import "tailwindcss";dansmain.css, puis on relancenpm run dev. Pas detailwind.config.js. - Les briques :
bg-,text-,p-/m-,border,rounded,flex/grid,gap-. - Mobile first : sans préfixe d'abord,
md:/lg:ensuite. - États :
hover:,focus-visible:,active:,disabled:. Le focus visible n'est pas négociable. - Pièges v4 :
bg-linear-to-r(pasbg-gradient-to-r), échelle des ombres décalée,ringà 1 px.
Sources
- Documentation officielle Tailwind CSS v4 — la barre de recherche en haut est le chemin le plus court.
- Guide d'installation avec Vite