Tableau de bord
Bienvenue dans votre espace d'administration. Le contenu principal prend tout l'espace restant grâce à flex: 1.
Le système de mise en page le plus utilisé du CSS moderne. Maîtriser la Flexbox, c'est maîtriser 90% des mises en page du web.
La Flexbox a révolutionné le CSS. Avant elle, créer une mise en page simple (centrer verticalement, aligner des éléments, créer un footer collant) nécessitait des hacks complexes. Avec Flexbox, c'est devenu trivial.
Le principe fondamental de la Flexbox repose sur deux axes :
AXE PRINCIPAL (Main Axis) ─────────────────────────►
┌─────────────────────────────────────────────────────┐
│ │
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ ▲
│ │ Item 1│ │ Item 2│ │ Item 3│ │ Item 4│ │ │
│ └───────┘ └───────┘ └───────┘ └───────┘ │ │
│ │ AXE
│ │ CROISÉ
│ │ (Cross
└─────────────────────────────────────────────────────┘ Axis)
▼
• Le conteneur = le parent avec display: flex
• Les items = les enfants directs
• L'axe principal = direction des items (row ou column)
• L'axe croisé = perpendiculaire à l'axe principal
Les deux axes fondamentaux de la Flexbox
| Avant Flexbox | Avec Flexbox |
|---|---|
| Centrer verticalement : hack complexe | align-items: center |
| Égaliser la hauteur des cartes : JavaScript | display: flex + align-items: stretch |
| Navbar logo à gauche, liens à droite : float | justify-content: space-between |
| Footer collant : hacks de hauteur | flex-direction: column + flex: 1 |
| Grille responsive : floats + media queries | flex-wrap: wrap + flex-basis |
| Ordonner visuellement les éléments : impossible | order |
display: flex transforme un élément en conteneur flex. Tous ses enfants directs deviennent automatiquement des items flexibles.
.conteneur {
display: flex; /* Conteneur flex — items en ligne */
display: inline-flex; /* Conteneur flex en ligne */
}
display: block (avant) → display: flex (après) ┌──────────────────┐ ┌──────────────────────┐ │ Item 1 │ │ Item 1 │ Item 2 │ I3 │ ├──────────────────┤ └──────────────────────┘ │ Item 2 │ ├──────────────────┤ Les items sont maintenant │ Item 3 │ en LIGNE et partagent └──────────────────┘ l'espace disponible
L'effet de display: flex sur des éléments block
.conteneur {
flex-direction: row; /* ← Défaut : gauche à droite */
flex-direction: row-reverse; /* → droite à gauche */
flex-direction: column; /* ↕ haut en bas */
flex-direction: column-reverse; /* ↑ bas en haut */
}
flex-direction: row (défaut) ┌─── 1 ──┬─── 2 ──┬─── 3 ──┐ Axe principal → │ Item1 │ Item2 │ Item3 │ Axe croisé ↓ └─────────┴─────────┴─────────┘ flex-direction: row-reverse ┌─── 3 ──┬─── 2 ──┬─── 1 ──┐ Axe principal ← │ Item3 │ Item2 │ Item1 │ Axe croisé ↓ └─────────┴─────────┴─────────┘ flex-direction: column ┌───────────────┐ Axe principal ↓ │ Item 1 │ Axe croisé → ├───────────────┤ │ Item 2 │ ├───────────────┤ │ Item 3 │ └───────────────┘ flex-direction: column-reverse ┌───────────────┐ Axe principal ↑ │ Item 3 │ Axe croisé → ├───────────────┤ │ Item 2 │ ├───────────────┤ │ Item 1 │ └───────────────┘
Les 4 valeurs de flex-direction
Démonstration : flex-direction
.conteneur {
flex-wrap: nowrap; /* Défaut — tout sur une ligne */
flex-wrap: wrap; /* Passage à la ligne si nécessaire */
flex-wrap: wrap-reverse; /* Passage à la ligne, axe croisé inversé */
}
flex-wrap: nowrap (défaut) ┌── 1 ──┬── 2 ──┬── 3 ──┬── 4 ──┬── 5 ──┐ │ ◄► │ ◄► │ ◄► │ ◄► │ ◄► │ ← Serrés/overflow └───────┴───────┴───────┴───────┴───────┘ flex-wrap: wrap ┌── 1 ──┬── 2 ──┬── 3 ──┐ │ │ │ │ ← Première ligne ├── 4 ──┬── 5 ──┐ │ │ │ ← Deuxième ligne └────────────────┘
nowrap vs wrap : le passage à la ligne
Démonstration : flex-wrap
.conteneur {
justify-content: flex-start; /* Début de l'axe */
justify-content: flex-end; /* Fin de l'axe */
justify-content: center; /* Centré */
justify-content: space-between; /* Espaces entre les items */
justify-content: space-around; /* Espaces autour de chaque item */
justify-content: space-evenly; /* Espaces identiques partout */
}
justify-content: flex-start
┌─[1]─┬─[2]─┬─[3]─┐ ▪▪▪▪
justify-content: flex-end
┌ ▪▪▪▪─[1]─┬─[2]─┬─[3]─┐
justify-content: center
┌ ▪▪▪▪─[1]─┬─[2]─┬─[3]─▪▪▪▪ ┐
justify-content: space-between
┌─[1]─▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪─[2]─▪▪▪▪▪─[3]─┐
justify-content: space-around
┌ ▪▪▪▪─[1]─▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪─[2]─▪▪▪▪▪▪▪▪▪▪▪▪─[3]─▪▪▪▪┐
↑ 1 unité ↑ 2 unités ↑ 2 unités ↑ 1 unité
justify-content: space-evenly
┌ ▪▪▪▪▪▪─[1]─▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪─[2]─▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪─[3]─▪▪▪▪▪▪▪▪┐
↑ 2 unités ↑ 2 unités ↑ 2 unités ↑ 2 unités
Les 6 valeurs de justify-content visualisées
Démonstration : justify-content
.conteneur {
align-items: stretch; /* Défaut — remplir la hauteur */
align-items: flex-start; /* Début de l'axe croisé */
align-items: flex-end; /* Fin de l'axe croisé */
align-items: center; /* Centré sur l'axe croisé */
align-items: baseline; /* Aligné sur la baseline du texte */
}
Démonstration : align-items
flex-wrap: wrap est actif et qu'il y a plusieurs lignes. N'a aucun effet si nowrap.
.conteneur {
flex-wrap: wrap;
align-content: flex-start; /* Lignes serrées en haut */
align-content: flex-end; /* Lignes serrées en bas */
align-content: center; /* Lignes centrées */
align-content: space-between; /* Espace entre les lignes */
align-content: space-around; /* Espace autour de chaque ligne */
align-content: space-evenly; /* Espace identique partout */
align-content: stretch; /* Lignes étirées (défaut) */
}
.conteneur {
gap: 1rem; /* Gap uniforme */
row-gap: 1rem; /* Gap vertical (entre les lignes) */
column-gap: 2rem; /* Gap horizontal (entre les colonnes) */
}
/* L'avantage de gap : pas de margin collapsing ! */
Démonstration : gap
.item {
flex-grow: 0; /* Défaut — ne grandit pas */
flex-grow: 1; /* Grandit pour remplir l'espace */
flex-grow: 2; /* Grandit 2× plus que flex-grow: 1 */
}
/* Exemple : sidebar 200px + contenu qui prend le reste */
.sidebar { flex: 0 0 200px; }
.contenu { flex: 1; } /* flex-grow: 1 shorthand */
flex-grow: 0 flex-grow: 1 flex-grow: 2 flex-grow: 3 ┌───┐ ┌───┬──────────┬──────────────────────────┐ │ 0 │ │ 1 │ 1 │ 2 │ └───┘ └───┴──────────┴──────────────────────────┘ fixe fixe grandit grandit 2× plus La distribution : 0:1:2:3 = 0/6 : 1/6 : 2/6 : 3/6 de l'espace
flex-grow comme facteur de proportion
Démonstration : flex-grow
flex-grow.
.item {
flex-shrink: 0; /* Ne rétrécit jamais — reste à sa taille */
flex-shrink: 1; /* Défaut — peut rétrécir */
flex-shrink: 2; /* Rétrécit 2× plus que flex-shrink: 1 */
}
/* Exemple : badges qui ne doivent jamais rétrécir */
.badge { flex-shrink: 0; }
.item {
flex-basis: auto; /* Défaut — taille du contenu */
flex-basis: 200px; /* Taille fixe de départ */
flex-basis: 50%; /* 50% de l'axe principal */
flex-basis: 0; /* Taille nulle → grandit avec flex-grow */
}
flex est un raccourci pour flex-grow, flex-shrink et flex-basis.
/* Shorthand : flex: grow shrink basis */
.item { flex: 1 1 0; } /* grow: 1, shrink: 1, basis: 0 */
.item { flex: 0 0 200px; } /* Largeur fixe 200px */
.item { flex: 1; } /* grow: 1, shrink: 1, basis: 0% */
.item { flex: 0 1 auto; } /* Ne grandit pas, peut rétrécir, taille auto */
/* Valeurs prédéfinies */
.item { flex: auto; } /* 1 1 auto */
.item { flex: none; } /* 0 0 auto — taille rigide */
.item { flex: 1; } /* 1 1 0% — prend l'espace disponible */
flex shorthand : flex: [grow] [shrink] [basis] ┌─────────────────────────────────────────────────────────────┐ │ flex: 1 1 0 → Grandit + rétrécit + taille 0 │ │ flex: 1 → Équivalent de flex: 1 1 0% │ │ flex: 0 0 200px → Taille rigide 200px │ │ flex: auto → 1 1 auto (taille du contenu) │ │ flex: none → 0 0 auto (ne bouge pas) │ └─────────────────────────────────────────────────────────────┘ Règle pratique : flex: 1 → "Prends tout l'espace disponible" flex: 0 → "Reste à ta taille" flex: 0 0 200px → "Fais 200px, point"
Les valeurs les plus courantes de flex
order ont une valeur de 0. Les valeurs négatives passent en premier.
.item-1 { order: 3; }
.item-2 { order: 1; }
.item-3 { order: 2; }
.item-4 { order: -1; } /* Passe en premier ! */
/* Résultat visuel : item-4, item-2, item-3, item-1 */
Démonstration : order
align-items du conteneur. Même syntaxe que align-items.
.conteneur {
display: flex;
align-items: stretch; /* Tous les items sont étirés */
}
.item-special {
align-self: center; /* Cet item est centré, pas étiré */
}
Démonstration : align-self
| Propriété | S'applique à | Description |
|---|---|---|
order |
Item | Ordre visuel |
flex-grow |
Item | Facteur d'expansion |
flex-shrink |
Item | Facteur de réduction |
flex-basis |
Item | Taille de départ |
flex |
Item | Raccourci grow/shrink/basis |
align-self |
Item | Override de align-items |
╔══════════════════════════════════════════════════════════════╗ ║ PROPRIÉTÉS DU CONTENEUR (parent) ║ ╠══════════════════════════════════════════════════════════════╣ ║ display: flex | inline-flex ║ ║ flex-direction: row | column | row-reverse | column-reverse║ ║ flex-wrap: nowrap | wrap | wrap-reverse ║ ║ justify-content: flex-start|end|center|space-between| ║ ║ space-around|space-evenly ║ ║ align-items: stretch|flex-start|flex-end|center|baseline ║ ║ align-content: (mêmes valeurs que justify-content) ║ ║ gap: [taille] | row-gap | column-gap ║ ╚══════════════════════════════════════════════════════════════╝ ╔══════════════════════════════════════════════════════════════╗ ║ PROPRIÉTÉS DES ITEMS (enfants directs) ║ ╠══════════════════════════════════════════════════════════════╣ ║ order: [nombre] ║ ║ flex-grow: [nombre] ║ ║ flex-shrink: [nombre] ║ ║ flex-basis: [taille] ║ ║ flex: [grow] [shrink] [basis] (shorthand) ║ ║ align-self: auto | flex-start|flex-end|center|stretch| ║ ║ baseline ║ ╚══════════════════════════════════════════════════════════════╝
Résumé visuel de toutes les propriétés Flexbox
flex-direction: row (défaut) ──────────────────────────► Axe principal (justify-content) │ [1] [2] [3] │ ▼ Axe croisé (align-items) flex-direction: column │ [1] │ [2] │ [3] ▼ Axe principal (justify-content) → Axe croisé (align-items) flex-direction: row-reverse ◄────────────────────────── Axe principal │ [3] [2] [1] │ ▼ Axe croisé flex-direction: column-reverse ▲ Axe principal │ [3] │ [2] │ [1] → Axe croisé
L'orientation des axes change avec flex-direction
display: flex — Activer Flexboxflex-direction: row|column — Directionflex-wrap: wrap — Multi-lignesgap: 1rem — Espacement itemsjustify-content: flex-startjustify-content: centerjustify-content: space-betweenjustify-content: space-aroundjustify-content: space-evenlyalign-items: stretch (défaut)align-items: center — Centrage Yalign-items: flex-start|endalign-items: baselineflex: 1 — Prend tout l'espaceflex: 0 0 200px — Taille fixeflex: none — Ne bouge pasorder: -1 — Passe en premieralign-self: center — Overridejustify-content: centeralign-items: centerplace-items: centerjustify-content: space-betweenflex: 0 0 250px + flex: 1flex-direction: column + flex: 1flex-wrap: wrap + flex-basis.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
}
.navbar-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
Rendu : Navbar
.footer-grid {
display: flex;
gap: 2rem;
flex-wrap: wrap;
}
.footer-col {
flex: 1;
min-width: 150px;
}
Rendu : Footer multi-colonnes
.layout {
display: flex;
gap: 1.5rem;
}
.sidebar {
flex: 0 0 200px; /* Largeur fixe */
}
.main-content {
flex: 1; /* Prend tout le reste */
}
Rendu : Sidebar + contenu principal
.header-cta {
display: flex;
align-items: center;
justify-content: space-between;
padding: 2rem 2.5rem;
flex-wrap: wrap; /* Responsive */
gap: 1rem;
}
Rendu : Header + Call-to-Action
La solution complète pour gérer vos projets efficacement.
.card-grid {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
.card {
flex: 1;
min-width: 200px;
display: flex; /* Items internes flex */
flex-direction: column;
}
.card-body {
flex: 1; /* Contenu étiré → cartes hautes égales */
}
/* La magie : display: flex sur la carte + flex:1 sur le body
= toutes les cartes ont la MÊME hauteur automatiquement */
Rendu : Cartes avec hauteurs égales
Un paragraphe beaucoup plus long qui s'étend sur plusieurs lignes pour montrer que les cartes s'alignent automatiquement grâce à Flexbox.
Voir plus.pricing {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
align-items: stretch; /* Cartes hautes égales */
}
.pricing-card {
flex: 1;
min-width: 200px;
display: flex;
flex-direction: column;
padding: 1.5rem;
}
.pricing-features {
flex: 1; /* Liste étirée → boutons alignés */
list-style: none;
padding: 0;
}
Rendu : Pricing table avec hauteur égale
.dashboard {
display: flex;
gap: 1rem;
min-height: 100vh;
}
.dash-sidebar {
flex: 0 0 60px; /* Sidebar icones */
display: flex;
flex-direction: column;
align-items: center;
}
.dash-main {
flex: 1;
display: flex;
flex-direction: column;
gap: 1rem;
}
.dash-stats {
display: flex;
gap: 1rem; /* Stats cards en ligne */
}
.dash-stat-card {
flex: 1; /* Cards égales */
}
Rendu : Dashboard
.timeline {
display: flex;
flex-direction: column;
gap: 0;
padding-left: 2rem;
position: relative;
}
.timeline::before {
content: "";
position: absolute;
left: 8px;
top: 0;
bottom: 0;
width: 2px;
background: #e2e8f0;
}
.timeline-item {
display: flex;
gap: 1rem;
position: relative;
padding-bottom: 1.5rem;
}
.timeline-item::before {
content: "";
position: absolute;
left: -1.55rem;
top: 0.3rem;
width: 12px;
height: 12px;
border-radius: 50%;
background: #2563eb;
}
Rendu : Timeline
Conception et architecture initiale du système.
Première version avec les fonctionnalités core implémentées.
Ouverture aux utilisateurs bêta avec collecte de feedback.
Mise en production et campagne de lancement.
.hero {
display: flex;
align-items: center;
justify-content: center;
min-height: 60vh;
text-align: center;
}
.hero-buttons {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
Rendu : Hero section
Maîtrisez CSS Flexbox et créez des mises en page professionnelles en quelques lignes de code.
.gallery {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.gallery-item {
flex: 1;
min-width: 150px;
min-height: 150px;
border-radius: 8px;
}
.gallery-item.wide {
flex: 2; /* Prend 2× la largeur */
}
Rendu : Galerie d'images
/* Le layout "Saint Graal" : header + nav + main + aside + footer */
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.hg-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.hg-body {
display: flex;
flex: 1; /* Prend tout l'espace vertical */
}
.hg-nav {
flex: 0 0 180px; /* Sidebar gauche fixe */
}
.hg-main {
flex: 1; /* Contenu principal */
}
.hg-aside {
flex: 0 0 200px; /* Sidebar droite fixe */
}
.hg-footer {
/* Collé en bas grâce au flex: 1 du body */
}
Rendu : Holy Grail Layout
Ce layout utilise flex: 1 pour que le contenu prenne tout l'espace disponible, et flex: 0 0 Xpx pour les sidebars de largeur fixe.
Sidebar droite avec du contenu secondaire.
/* Méthode 1 : Flexbox (la meilleure) */
.centree-flex {
display: flex;
justify-content: center;
align-items: center;
}
/* Méthode 2 : Grid (la plus concise) */
.centree-grid {
display: grid;
place-items: center;
}
/* Méthode 3 : margin auto dans un flex */
.centree-margin {
display: flex;
}
.centree-margin .enfant {
margin: auto; /* Centré horizontalement ET verticalement */
}
/* Méthode 4 : Position + transform (classique) */
.centree-position {
position: relative;
}
.centree-position .enfant {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Méthode 5 : text-align + line-height (texte) */
.centree-texte {
text-align: center;
line-height: 150px; /* = hauteur du conteneur */
}
Rendu : 5 méthodes de centrage
/* FAUX — les propriétés flex n'ont aucun effet */
.parent {
justify-content: center; /* Ignoré ! */
}
.parent .enfant {
flex: 1; /* Ignoré ! */
}
/* CORRECT — activer Flexbox d'abord */
.parent {
display: flex; /* Obligatoire ! */
justify-content: center;
}
/* ANCIEN — hacks compliqués */
.centree {
width: 300px;
margin: 0 auto; /* Centre X mais pas Y */
}
/* MODERNE — une seule ligne */
.centree {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
/* FAUX — flex-direction doit être sur le PARENT */
.enfant {
flex-direction: row; /* Ignoré — ce n'est pas un conteneur */
}
/* CORRECT */
.parent {
display: flex;
flex-direction: row; /* Sur le conteneur */
}
/* FAUX — l'enfant ne peut pas prendre 100% sans parent height */
.parent {
display: flex;
flex-direction: column;
}
.enfant {
height: 100%; /* 100% de quoi ? Parent n'a pas de height ! */
}
/* CORRECT */
.parent {
display: flex;
flex-direction: column;
height: 100vh; /* Le parent a une hauteur */
}
.enfant {
flex: 1; /* Prend tout l'espace restant */
}
/* Justify-content = axe PRINCIPAL (row = gauche→droite) */
/* Align-items = axe CROISÉ (row = haut→bas) */
.conteneur {
display: flex;
justify-content: center; /* Centre GAUCHE → DROITE */
align-items: center; /* Centre HAUT → BAS */
}
/* Si flex-direction: column, les axes s'inversent ! */
.conteneur {
flex-direction: column;
justify-content: center; /* Centre HAUT → BAS (axe principal) */
align-items: center; /* Centre GAUCHE → DROITE (axe croisé) */
}
/* FAUX — peut dépasser la largeur du conteneur */
.item {
flex: 1 0 300px; /* flex-shrink: 0 → ne rétrécit JAMAIS */
}
/* CORRECT — laisser flex-shrink: 1 pour le responsive */
.item {
flex: 1 1 300px; /* Peut grandir ET rétrécir */
}
/* OU pour un sidebar fixe */
.sidebar {
flex: 0 0 250px; /* Ne grandit pas, ne rétrécit pas */
}
/* ANCIEN — risque de margin collapsing et last-child */
.item {
margin-bottom: 1rem;
}
.item:last-child {
margin-bottom: 0; /* Hack pour le dernier */
}
/* MODERNE — gap, pas de collapsing */
.conteneur {
display: flex;
gap: 1rem; /* Espacement uniforme, pas de last-child */
}
/* FAUX — tous les items prennent la même taille */
.item { flex: 1; } /* 4 items = chacun 25% */
/* CORRECT — garder des items de taille fixe quand nécessaire */
.sidebar-item { flex: 0 0 auto; } /* Taille du contenu */
.main-item { flex: 1; } /* Prend le reste */
| Situation | Propriété recommandée |
|---|---|
| Centrer horizontalement | justify-content: center |
| Centrer verticalement | align-items: center |
| Centrer les deux axes | Les deux combinés, ou display: grid; place-items: center |
| Sidebar + contenu | flex: 0 0 250px + flex: 1 |
| Cartes hautes égales | display: flex; flex-direction: column sur la carte + flex: 1 sur le body |
| Footer collant | flex-direction: column; min-height: 100vh + flex: 1 sur le main |
| Navbar logo/liens | justify-content: space-between |
| Grille responsive | flex-wrap: wrap + flex: 1 1 300px |
| Items empilés avec espace | flex-direction: column; gap: 1rem |
| Réordonner visuellement | order sur l'item |
/* Navbar : logo à gauche, liens à droite */
.navbar { display: flex; align-items: center; justify-content: space-between; }
/* Sidebar layout */
.layout { display: flex; gap: 1.5rem; }
.sidebar { flex: 0 0 250px; }
.content { flex: 1; }
/* Footer collant */
body { display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; }
/* Cartes égales */
.cards { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.card { flex: 1 1 250px; display: flex; flex-direction: column; }
.card-body { flex: 1; }
/* Grille responsive sans media query */
.grid { display: flex; flex-wrap: wrap; gap: 1rem; }
.grid-item { flex: 1 1 250px; }
/* Input group */
.input-group { display: flex; }
.input-group input { flex: 1; }
.input-group button { flex: 0; }
/* Centrage universel */
.center { display: flex; align-items: center; justify-content: center; }
Défi 1 : Navbar responsive
Créez une navbar avec :
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
@media (max-width: 768px) {
.navbar { flex-direction: column; gap: 1rem; }
}
Défi 2 : Centrage parfait
Centrez un bloc de 200×200px au centre exact de la page en utilisant 3 méthodes différentes.
/* Méthode 1 : Flexbox */
body { display: flex; justify-content: center; align-items: center; min-height: 100vh; }
/* Méthode 2 : Grid */
body { display: grid; place-items: center; min-height: 100vh; }
/* Méthode 3 : margin auto dans flex */
body { display: flex; min-height: 100vh; }
.box { width: 200px; height: 200px; margin: auto; }
Défi 3 : Footer collant
Créez un layout avec un header, un contenu court et un footer toujours collé en bas de la page, même quand le contenu est petit.
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1; /* Prend tout l'espace restant */
}
Défi 4 : Galerie responsive
Créez une galerie de cartes qui :
.gallery {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.gallery-item {
flex: 1 1 calc(33.333% - 1rem);
display: flex;
flex-direction: column;
}
@media (max-width: 768px) {
.gallery-item { flex: 1 1 calc(50% - 1rem); }
}
@media (max-width: 480px) {
.gallery-item { flex: 1 1 100%; }
}
Défi 5 : Holy Grail avec flex
Créez le layout "Holy Grail" complet : header, sidebar gauche, contenu principal, sidebar droite, footer. Le footer doit rester en bas.
Projet 1 : Page de pricing responsive
Créez une page de tarification avec 3 plans :
align-items: stretchflex-wrap: wrap + min-width: 250px pour le responsiveflex: 1 pour aligner les boutons en basProjet 2 : Dashboard admin
Créez un tableau de bord admin avec :
flex: 0 0 60px)justify-content: space-between)display: flex; gap)flex: 1)Projet 3 : Portfolio créatif
Créez un portfolio avec :
display: flex; align-items: center; justify-content: centerflex-wrap: wrap et flex: 1 1 300pxdisplay: flex; flex-direction: column pour hauteur égaletransform: scale(1.05)Projet 4 : Layout de blog
Créez un layout de blog avec :
flex: 1 + flex: 0 0 300px)flex-wrap: wrap| Concept | Propriété | Valeurs courantes |
|---|---|---|
| Activer Flexbox | display |
flex, inline-flex |
| Direction | flex-direction |
row, column, row-reverse, column-reverse |
| Retour à la ligne | flex-wrap |
nowrap, wrap, wrap-reverse |
| Alignement principal | justify-content |
flex-start, center, space-between, space-around, space-evenly |
| Alignement croisé | align-items |
stretch, center, flex-start, flex-end |
| Gap | gap |
Taille CSS : 1rem, 1.5rem, etc. |
| Expansion | flex-grow |
0 (défaut), 1, 2, etc. |
| Réduction | flex-shrink |
1 (défaut), 0, 2, etc. |
| Taille de départ | flex-basis |
auto, 0, 200px, 50% |
| Raccourci | flex |
1, 0 0 200px, auto, none |
| Ordre visuel | order |
-1, 0 (défaut), 1, 2, etc. |
| Override alignement | align-self |
auto, center, stretch, etc. |
justify-content et align-items ?flex permet à un item de prendre tout l'espace disponible ?gap par rapport aux marges pour l'espacement ?align-items du conteneur ?flex: 1 et flex: 0 0 200px ?display: flexjustify-content aligne sur l'axe principal, align-items sur l'axe croiséflex: 1 (shorthand de flex-grow: 1; flex-shrink: 1; flex-basis: 0%).sidebar { flex: 0 0 250px; } + .content { flex: 1; }align-items: center:last-childflex-wrap: wraporder (valeur négative = premier, positive = dernier)align-selfflex: 1 grandit et rétrécit dynamiquement, flex: 0 0 200px est une taille rigide de 200px/* Centrer dans un conteneur */
.conteneur { display: flex; justify-content: center; align-items: center; }
/* Sidebar + contenu */
.layout { display: flex; gap: 1.5rem; }
.sidebar { flex: 0 0 250px; }
.main { flex: 1; }
/* Footer collant */
body { display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; }
/* Cartes hautes égales */
.cards { display: flex; flex-wrap: wrap; gap: 1rem; }
.card { flex: 1; min-width: 250px; display: flex; flex-direction: column; }
.card-body { flex: 1; }
/* Galerie responsive */
.gallery { display: flex; flex-wrap: wrap; gap: 1rem; }
.gallery-item { flex: 1 1 250px; }
/* Navbar */
.navbar { display: flex; align-items: center; justify-content: space-between; }
/* Input group */
.input-group { display: flex; }
.input-group input { flex: 1; }