Niveau 8 — Box Model

Le Box Model

Le chapitre le plus important du cours. Maîtriser le modèle de boîte est la clé pour créer n'importe quelle mise en page.

1. Comprendre le Box Model

En une phrase : Chaque élément HTML est une boîte rectangulaire composée de 4 zones concentriques : contenu, padding, bordure et marge.

Le Box Model est le concept fondamental de CSS. Il définit comment chaque élément est rendu sur la page et comment il interagit avec les éléments voisins. Sans comprendre le Box Model, il est impossible de créer des mises en page correctes.

Chaque élément HTML génère une boîte rectangulaire qui se compose de 4 zones, de l'intérieur vers l'extérieur :

Zone Propriété CSS Description
Contenu (Content) width, height Le texte, l'image ou le contenu interne
Rembourrage (Padding) padding Espace entre le contenu et la bordure
Bordure (Border) border La ligne qui entoure le padding
Marge (Margin) margin Espace extérieur entre cette boîte et les autres
Analogie : Imagine un colis. Le contenu est le produit, le padding est le papier bulle de protection, la bordure est la boîte en carton, et la marge est l'espace entre ce colis et les autres sur l'étagère.

2. Syntaxe détaillée

2.1 Le modèle de boîte — Vue d'ensemble

Dimensions du conteneur : width / height

Définition : Définissent la largeur et la hauteur de la zone de contenu (par défaut) ou de la boîte entière (avec border-box).
/* Toutes les unités sont acceptées */
.boite {
  width: 300px;
  height: 200px;
}

/* Pourcentages — relatif au parent */
.boite {
  width: 50%;
  height: 100vh;
}

/* Auto — le navigateur calcule */
.boite {
  width: auto;     /* Défaut — prend toute la largeur disponible */
  height: auto;    /* Défaut — s'adapte au contenu */
}

/* Valeurs spéciales */
.boite {
  width: fit-content;    /* Taille du contenu */
  width: min-content;    /* Taille minimale du contenu */
  width: max-content;    /* Taille maximale du contenu */
}

min-width / max-width / min-height / max-height

Définition : Imposent des limites min/max aux dimensions d'un élément. Très utile pour le responsive.
.boite-responsive {
  width: 100%;
  min-width: 320px;    /* Jamais plus étroit que 320px */
  max-width: 1200px;   /* Jamais plus large que 1200px */
  min-height: 200px;   /* Hauteur minimale garantie */
  max-height: 80vh;    /* Ne dépasse jamais 80% de la viewport */
}

/* Utilisation courante : conteneur centré */
.conteneur {
  width: 100%;
  max-width: 900px;
  margin-left: auto;
  margin-right: auto;
}

Démonstration : min/max width

width: 100% — min-width: 200px — max-width: 500px

Redimensionne la fenêtre pour voir l'effet.

aspect-ratio — Ratio d'aspect moderne

Définition : Définit le ratio entre la largeur et la hauteur d'un élément. Remplace le fameux padding-top hack.
/* Ratio 16:9 — vidéo YouTube */
.video {
  width: 100%;
  aspect-ratio: 16 / 9;
}

/* Carré parfait */
.avatar {
  width: 100px;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
}

/* Ratio 4:3 */
.image {
  width: 100%;
  aspect-ratio: 4 / 3;
}

/* Ancienne méthode (à éviter) — padding-top hack */
.ancien {
  width: 100%;
  padding-top: 56.25%; /* 9/16 × 100% */
  position: relative;
}
.nouveau {
  width: 100%;
  aspect-ratio: 16 / 9; /* Simple et lisible */
}

Démonstration : aspect-ratio

16 : 9
4 : 3
1 : 1

2.2 box-sizing — La propriété la plus importante

Définition : Contrôle comment la largeur et la hauteur sont calculées. C'est la propriété CSS la plus critique à comprendre.
/* Valeur par défaut : content-box */
.boite-defaut {
  box-sizing: content-box;
  width: 300px;
  padding: 20px;
  border: 5px solid #000;
  /* Largeur totale = 300 + 20×2 + 5×2 = 350px ! */
}

/* Valeur recommandée : border-box */
.boite-recommandee {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 5px solid #000;
  /* Largeur totale = 300px (le padding et border sont inclus) */
}
┌─ MARGIN (20px) ────────────────────────────────────┐
│  ┌─ BORDER (5px) ───────────────────────────────┐  │
│  │  ┌─ PADDING (20px) ────────────────────────┐  │  │
│  │  │                                         │  │  │
│  │  │   width: 300px (CONTENT)                │  │  │
│  │  │                                         │  │  │
│  │  └─────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘

  content-box : width = contenu seul (300px)
  border-box  : width = contenu + padding + border (300px total)

Comparaison entre content-box et border-box

Comparaison interactive : content-box vs border-box

box-sizing: content-box (défaut)
width: 300px
padding: 20px
border: 5px
Total: 350px
box-sizing: border-box (recommandé)
width: 300px
padding: 20px
border: 5px
Total: 300px
Le reset universel : Utilise border-box sur TOUS les éléments. C'est la pratique la plus recommandée en CSS moderne.
*, *::before, *::after {
  box-sizing: border-box;
}

Pourquoi border-box est mieux :

  • La width correspond à ce que vous voyez à l'écran
  • Les pourcentages fonctionnent intuitivement
  • Pas besoin de calculer padding + border en plus
  • Les grilles CSS et Flexbox sont plus simples
  • C'est ce que font 99% des frameworks CSS modernes

2.3 Margin — L'espace extérieur

Shorthand margin

Définition : La marge (margin) est l'espace extérieur d'un élément. Elle sépare la boîte des éléments voisins.
/* 1 valeur : toutes les côtés */
.boite { margin: 20px; }

/* 2 valeurs : haut/bas — gauche/droite */
.boite { margin: 10px 20px; }

/* 3 valeurs : haut — gauche/droite — bas */
.boite { margin: 10px 20px 30px; }

/* 4 valeurs : haut — droite — bas — gauche (sens horaire) */
.boite { margin: 10px 20px 30px 40px; }

/* Côtés individuels */
.boite {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 30px;
  margin-left: 40px;
}

/* Auto — centrage horizontal */
.boite-centree {
  width: 300px;
  margin-left: auto;
  margin-right: auto;
  /* Ou raccourci : */
  margin: 0 auto;
}
margin: 10px 20px 30px 40px;
          │    │    │    │
          │    │    │    └── gauche (40px)
          │    │    └─── bas (30px)
          │    └──── droite (20px)
          └───── haut (10px)

         ┌─ 10px ─┐
    ┌────┼────────┼────┐
40px│    │  BOÎTE │    │20px
    │    │        │    │
    └────┼────────┼────┘
         └─ 30px ─┘

Ordre des valeurs : haut, droite, bas, gauche (sens horaire)

Marge négative

Définition : Une marge peut être négative, ce qui a pour effet de reculer l'élément ou de le faire déborder de son conteneur.
/* Reculer un élément vers la gauche */
.decale {
  margin-left: -20px;
}

/* Faire chevaucher deux éléments */
.chevauchement {
  margin-top: -30px;  /* Remonte l'élément */
}

/* Déborder du conteneur */
.bande-pleine-largeur {
  width: 100vw;
  margin-left: calc(-50vw + 50%);
}

Démonstration : marge négative

Box 1 — margin-bottom: 0
Box 2 — margin-top: -20px (chevauche Box 1)

Margin collapsing — Le piège n°1

Définition : Quand deux marges verticales se touchent, elles fusionnent en une seule marge dont la valeur est la plus grande des deux. Cela ne se produit jamais avec les marges horizontales.
/* Règle : les marges verticales adjacentes fusionnent */
.block-1 {
  margin-bottom: 30px;
}
.block-2 {
  margin-top: 20px;
}
/* Espace réel entre les deux : 30px (pas 50px !) */

/* Résultat visuel :
   ┌─ Block 1 ─┐
   │            │
   └────────────┘
   ↕ 30px (pas 50px)
   ┌─ Block 2 ─┐
   │            │
   └────────────┘
*/
MARGIN COLLAPSING — Les marges verticales fusionnent
═══════════════════════════════════════════════════════

  Sans collapsing (ce qu'on pourrait attendre) :
  ┌──────────┐
  │  Block 1 │
  └──────────┘
  ↕ 30px (margin-bottom de Block 1)
  ↕ 20px (margin-top de Block 2)
  ┌──────────┐
  │  Block 2 │
  └──────────┘

  Avec collapsing (ce qui se passe réellement) :
  ┌──────────┐
  │  Block 1 │
  └──────────┘
  ↕ 30px (max(30px, 20px) = 30px)
  ┌──────────┐
  │  Block 2 │
  └──────────┘

  La marge résultante = max(margin-bottom, margin-top)

Le margin collapsing : les marges verticales fusionnent en prenant la plus grande valeur

Démonstration : Margin collapsing

Box 1 margin-bottom: 40px
Box 2 margin-top: 25px
Espace réel : 40px (pas 65px !) — La marge a fusionné.
Comment éviter le margin collapsing ?
  • Créer un formatting context : overflow: auto, display: flow-root, display: flex, display: grid
  • Ajouter un padding ou une border au conteneur parent
  • Utiliser gap avec flexbox/grid (ne collapse pas)
Les 3 cas de margin collapsing :
  1. Éléments adjacents — margin-bottom du premier + margin-top du second
  2. Parent et premier/enfant — la marge-top du premier enfant « passe à travers » le parent si celui-ci n'a pas de padding/border
  3. Éléments vides — les marges top et bottom d'un élément sans contenu fusionnent

2.4 Padding — L'espace intérieur

Définition : Le padding est l'espace intérieur entre le contenu et la bordure. Il « gonfle » l'élément de l'intérieur.
/* Shorthand identique à margin */
.boite { padding: 20px; }             /* Toutes les côtés */
.boite { padding: 10px 20px; }       /* Haut/bas — gauche/droite */
.boite { padding: 10px 20px 30px; }  /* Haut — gauche/droite — bas */
.boite { padding: 10px 20px 30px 40px; } /* Haut — droite — bas — gauche */

/* Côtés individuels */
.boite {
  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 30px;
  padding-left: 40px;
}

Padding vs Margin

MARGIN (extérieur)
BORDER
PADDING (intérieur)
CONTENU
Critère Padding Margin
Position Intérieur (entre contenu et bordure) Extérieur (entre boîtes)
Couleur de fond Voit la couleur de fond du parent Toujours transparente
Collapsing Non Oui (verticalement)
Valeurs négatives Non (non supporté) Oui
Centrage d'éléments Non Oui (margin: auto)
Impact sur la taille Oui (augmente la taille de la boîte) Non (l'espace est en dehors)

2.5 Border — La bordure

Définition : La bordure entoure le padding et le contenu. Elle a trois propriétés : épaisseur, style et couleur.
/* Propriétés individuelles */
.boite {
  border-width: 2px;
  border-style: solid;
  border-color: #333;
}

/* Shorthand */
.boite {
  border: 2px solid #333;
}

/* Bordures individuelles */
.boite {
  border-top: 3px solid red;
  border-right: 1px dashed blue;
  border-bottom: 3px solid red;
  border-left: 1px dashed blue;
}

/* Bordures arrondies */
.boite {
  border-radius: 8px;              /* Tous les coins */
  border-radius: 8px 0;           /* Coins horizontaux / coins verticaux */
  border-radius: 8px 0 8px 0;     /* Haut-gauche — haut-droit — bas-droit — bas-gauche */
  border-radius: 50%;             /* Cercle/ellipse */
}
border-style Rendu
nonePas de bordure
solidLigne pleine
dashedTirets
dottedPointillés
doubleDouble ligne
grooveGravure 3D
ridgeCrête 3D
insetEnfoncé
outsetEn relief
hiddenMasquée (comme none mais dans le modèle)

Démonstration : Styles de bordure

solid
dashed
dotted
double
groove
ridge

border-collapse — Pour les tableaux

Définition : Spécifie si les bordures des cellules d'un tableau sont fusionnées ou séparées.
table {
  border-collapse: collapse;  /* Bordures fusionnées */
  /* OU */
  border-collapse: separate;  /* Bordures séparées (défaut) */
  border-spacing: 8px;       /* Espacement entre cellules */
}

Comparaison : border-collapse

border-collapse: collapse
ABC
123
456
border-collapse: separate
ABC
123
456

2.6 Overflow — Gestion du dépassement

Définition : Contrôle ce qui se passe quand le contenu d'un élément dépasse ses dimensions.
.boite { overflow: visible; }   /* Défaut — le contenu déborde */
.boite { overflow: hidden; }    /* Le contenu est coupé */
.boite { overflow: scroll; }    /* Barres de défilement toujours visibles */
.boite { overflow: auto; }      /* Barres de défilement si nécessaire */

/* Directionnel */
.boite { overflow-x: hidden; }  /* Coupé horizontalement */
.boite { overflow-y: scroll; }  /* Défilement vertical */

/* Nouvelles valeurs modernes */
.boite { overflow: clip; }      /* Comme hidden mais sans scroll */
.boite { overflow: clip; }      /* Plus performant que hidden */
Valeur Contenu déborde ? Scroll Usage
visible Oui (défaut) Non Éléments extensible (défaut)
hidden Non — coupé Non Cacher le débordement
scroll Non — scrollable Toujours visible Quand on veut toujours le scroll
auto Non — scrollable Si nécessaire Le plus courant
clip Non — coupé (sans scroll possible) Non Plus performant que hidden

Démonstration : overflow

overflow: visible (défaut)
Ce contenu est très long et il déborde visiblement de la boîte sans aucune restriction. On peut le voir en dehors des limites de l'élément parent.
overflow: hidden
Ce contenu est très long et il est coupé lorsque la boîte ne peut plus le contenir. Le texte disparaît brutalement.
overflow: auto
Ce contenu est très long et il active une barre de défilement automatique quand la boîte ne peut plus le contenir confortablement.
clip vs hidden : overflow: clip est plus performant car il ne crée pas un contexte de défilement. Utilisez-le quand vous n'avez besoin d'aucun scroll.

2.7 Outline — Contour externe

Définition : Un contour (outline) est une ligne qui entoure la bordure. Contrairement à border, il ne prend pas de place dans le modèle de boîte.
.boite:focus {
  outline: 3px solid #2563eb;
  outline-offset: 4px;  /* Espace entre la bordure et le contour */
}

/* Supprimer le focus ring (à éviter pour l'accessibilité !) */
.boite:focus { outline: none; }

/* Remplacement moderne et accessible */
.boite:focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}

Comparaison : outline vs border

border: 4px solid (prend de la place)
border ajoute de la largeur à la boîte
outline: 4px solid (ne prend PAS de place)
outline n'affecte pas la taille de la boîte
Critère Border Outline
Place dans le modèle Oui (augmente la taille) Non
Shape Suit le border-radius Toujours rectangulaire
Côtés individuels Oui Non
offset Non Oui (outline-offset)
Usage principal Décoration visuelle Focus ring (accessibilité)

3. Visualisation

3.1 Diagramme complet du Box Model

┌─────────────────── MARGIN ───────────────────────────┐
│  (transparente — espace entre les éléments)          │
│                                                      │
│  ┌────────────── BORDER ──────────────────────────┐  │
│  │  (ligne visible — border-width, border-style)  │  │
│  │                                                 │  │
│  │  ┌────────── PADDING ───────────────────────┐  │  │
│  │  │  (espace intérieur — couleur de fond)    │  │  │
│  │  │                                          │  │  │
│  │  │  ┌──────── CONTENT ───────────────────┐  │  │  │
│  │  │  │                                    │  │  │  │
│  │  │  │  Le texte, l'image, le contenu     │  │  │  │
│  │  │  │                                    │  │  │  │
│  │  │  │  width × height                    │  │  │  │
│  │  │  │                                    │  │  │  │
│  │  │  └────────────────────────────────────┘  │  │  │
│  │  │                                          │  │  │
│  │  └──────────────────────────────────────────┘  │  │
│  │                                                 │  │
│  └─────────────────────────────────────────────────┘  │
│                                                      │
└──────────────────────────────────────────────────────┘

width  = content-width + padding-left + padding-right + border-left + border-right
height = content-height + padding-top + padding-bottom + border-top + border-bottom

Le Box Model complet avec toutes ses zones

3.2 Box-sizing comparison

content-box (défaut) :
═══════════════════════
  ┌─ padding ─┐
  │  ┌──────┐ │
  │  │conten│ │  ← width: 200px (contenu seul)
  │  │  u   │ │     + padding: 20px × 2
  │  └──────┘ │     + border: 5px × 2
  └───────────┘     = 250px TOTAL

border-box (recommandé) :
══════════════════════════
  ┌─ padding ─┐
  │  ┌──────┐ │
  │  │conten│ │  ← width: 200px (tout inclus !)
  │  │  u   │ │     padding et border sont
  │  └──────┘ │     DÉDUITS du width
  └───────────┘     = 200px TOTAL

Avec border-box, width = taille totale visible

3.3 Margin collapsing — Cas visuels

CAS 1 : Deux blocs adjacents
─────────────────────────────
  ┌──────────┐
  │  Bloc 1  │  margin-bottom: 30px
  └──────────┘
      ↕ 30px  ← max(30, 20) = 30px
  ┌──────────┐
  │  Bloc 2  │  margin-top: 20px
  └──────────┘

CAS 2 : Parent + premier enfant
─────────────────────────────────
  ┌─── Parent (sans padding) ────┐
  │  ↕ 20px ← "s'échappe"       │
  │  ┌── Enfant 1 ──┐           │
  │  │               │ margin-top: 20px
  │  └───────────────┘           │
  │  ┌── Enfant 2 ──┐           │
  │  │               │           │
  │  └───────────────┘           │
  └──────────────────────────────┘

CAS 3 : Parent AVEC padding ou border
──────────────────────────────────────
  ┌─── Parent (border ou padding) ─┐
  │                                 │
  │  ↕ 20px ← ne s'échappe PAS    │
  │  ┌── Enfant 1 ──┐             │
  │  │               │ margin-top: 20px
  │  └───────────────┘             │
  │  ┌── Enfant 2 ──┐             │
  │  │               │             │
  │  └───────────────┘             │
  └────────────────────────────────┘

Les trois cas de margin collapsing et comment les éviter

4. Exemples progressifs

4.1 Le reset CSS universel

Le reset que tout le monde devrait utiliser

/* Reset moderne — utilise border-box sur tout */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Supprime les marges par défaut des éléments de liste */
ul, ol {
  list-style: none;
}

/* Empêche les images de déborder */
img, video {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Empêche le texte de déborder */
p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

4.2 Techniques de centrage

5 façons de centrer un élément avec le box model

/* Méthode 1 : margin auto (l'élément a une width) */
.centree-1 {
  width: 300px;
  margin: 0 auto;
}

/* Méthode 2 : margin auto + Flexbox (le conteneur est flex) */
.centree-2 {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Méthode 3 : margin auto dans un Grid */
.centree-3 {
  display: grid;
  place-items: center;
}

/* Méthode 4 : transform (absolu + décalage) */
.centree-4 {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* Méthode 5 : padding (quand on veut de l'espace) */
.centree-5 {
  width: fit-content;
  margin: 0 auto;
  padding: 2rem;
}
margin: 0 auto
Centrée
Flexbox center
Centrée

4.3 Carte avec padding et border

Composant carte stylisé avec le Box Model

.carte {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.2s, transform 0.2s;
}

.carte:hover {
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.carte__titre {
  font-size: 1.25rem;
  font-weight: 700;
  margin-bottom: 0.5rem;  /* Espace sous le titre */
}

.carte__texte {
  color: #64748b;
  line-height: 1.6;
  margin-bottom: 1rem;     /* Espace avant le bouton */
}

.carte__bouton {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: #2563eb;
  color: white;
  border-radius: 6px;
  border: none;
  font-weight: 600;
  cursor: pointer;
}

Titre de la carte

Ceci est un exemple de carte utilisant padding pour l'espacement interne, border pour la bordure, et border-radius pour les coins arrondis.

4.4 Layout responsive avec box-sizing

Mise en page qui fonctionne à 100%

/* Avec border-box, les pourcentages fonctionnent parfaitement */
.conteneur {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
}

.layout {
  display: flex;
  gap: 2rem;     /* Pas de margin collapsing avec gap ! */
}

.sidebar {
  flex: 0 0 250px;  /* Largeur fixe */
  padding: 1.5rem;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

.contenu {
  flex: 1;           /* Prend le reste */
  padding: 1.5rem;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

/* Sur mobile, passer en colonnes */
@media (max-width: 768px) {
  .layout {
    flex-direction: column;
  }
  .sidebar {
    flex: none;
  }
}

4.5 Espacement harmonieux avec gap

Gap : l'alternative moderne aux marges

/* AVANT — Avec margin (risque de collapsing) */
.liste-item {
  margin-bottom: 1rem;
}
.liste-item:last-child {
  margin-bottom: 0;  /* Supprimer la marge du dernier */
}

/* APRÈCES — Avec gap (pas de collapsing !) */
.liste {
  display: flex;
  flex-direction: column;
  gap: 1rem;  /* Espacement uniforme, pas de last-child */
}

/* Grid avec gap */
.grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;  /* Gap horizontal ET vertical */
}

/* gap fonctionne aussi avec flexbox */
.flex-gap {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
Avec margin (avant)
Item 1
Item 2
Item 3
Avec gap (après)
Item 1
Item 2
Item 3

5. Erreurs fréquentes

Erreur 1 : Oublier box-sizing: border-box
/* FAUX — width ne correspond pas à la taille visible */
.boite {
  width: 300px;
  padding: 20px;
  border: 5px solid #000;
  /* Total visible = 350px, pas 300px ! */
}

/* CORRECT — border-box en premier */
*, *::before, *::after {
  box-sizing: border-box;
}
.boite {
  width: 300px;
  padding: 20px;
  border: 5px solid #000;
  /* Total visible = 300px ✓ */
}
Erreur 2 : Utiliser margin: auto pour centrer verticalement
/* FAUX — margin: auto ne centre que horizontalement */
.boite {
  margin: 0 auto;  /* Centre gauche/droite ✓ */
  margin: auto 0;  /* NE centre PAS haut/bas ✗ */
}

/* CORRECT — pour centrer verticalement */
.boite {
  display: flex;
  justify-content: center;
  align-items: center;
}
/* OU */
.boite {
  display: grid;
  place-items: center;
}
Erreur 3 : Confondre padding et margin
/* FAUX — penser que margin ajoute de la couleur de fond */
.boite {
  margin: 20px;
  background: blue;  /* Le margin reste transparent ! */
}

/* CORRECT — utiliser padding pour l'espacement avec fond */
.boite {
  padding: 20px;     /* Le padding prend la couleur de fond */
  background: blue;
}
Erreur 4 : Appliquer margin sur un élément inline
/* FAUX — les marges horizontales fonctionnent, pas les verticales */
span {
  margin-top: 20px;   /* Ignoré ! */
  margin-bottom: 20px; /* Ignoré ! */
  margin-left: 20px;   /* Fonctionne */
}

/* CORRECT — convertir en inline-block ou block */
span {
  display: inline-block;
  margin: 20px;
}
Erreur 5 : Width sur un élément sans width explicite
/* FAUX — un bloc prend 100% par défaut, pas la taille du contenu */
div { background: blue; }
/* Le div fait toute la largeur du parent */

/* CORRECT — spécifier une width ou utiliser fit-content */
div {
  width: fit-content;  /* S'adapte au contenu */
  background: blue;
}
Erreur 6 : Utiliser width: 100% avec padding dans content-box
/* FAUX — le padding AJOUTE à la largeur */
.boite-content {
  box-sizing: content-box;  /* Défaut */
  width: 100%;
  padding: 20px;
  /* Total = 100% + 40px → déborde ! */
}

/* CORRECT — utiliser border-box ou max-width */
.boite-border {
  box-sizing: border-box;
  width: 100%;
  padding: 20px;
  /* Total = 100% → parfait */
}
Erreur 7 : Ne pas tenir compte du margin collapsing
/* FAUX — les espaces ne sont pas ce qu'on attend */
.parent {
  background: #f1f5f9;
}
.enfant-1 { margin-bottom: 30px; }
.enfant-2 { margin-top: 20px; }
/* Espace entre les enfants : 30px, pas 50px ! */

/* CORRECT — utiliser gap ou un formatting context */
.parent {
  display: flex;
  flex-direction: column;
  gap: 20px;  /* Espacement exact et prévisible */
}
Erreur 8 : Mettre des marges négatives sans comprendre les conséquences
/* FAUX — les marges négatives cassent le layout */
.decalage {
  margin-top: -50px;  /* Remonte l'élément, chevauche le précédent */
  margin-left: -20px; /* Sort du conteneur */
}
/* Les résultats sont souvent imprévisibles et cassent le responsive */

/* CORRECT — utiliser les outils modernes à la place */
.decalage {
  transform: translateY(-10px);  /* Décalage visuel sans casser le layout */
}

6. Bonnes pratiques

Les règles d'or du Box Model :
  • Toujours border-box — le reset * { box-sizing: border-box; } est non négociable.
  • Préférer gap aux marges dans les layouts flex/grid — pas de collapsing, plus prévisible.
  • max-width au lieu de width pour les conteneurs — évite le débordement sur grand écran.
  • Ne jamais utiliser margin: 0 auto pour le centrage vertical — utiliser flexbox ou grid.
  • Éviter les marges négatives sauf cas très spécifiques — préférer transform.
  • Comprendre le margin collapsing avant de chercher à l'éviter.
  • Utiliser aspect-ratio au lieu du padding-top hack pour les ratios vidéo.
  • overflow: auto pour créer un formatting context (évite le collapsing).
  • padding pour l'espacement interne, margin pour l'externe — ne pas mélanger.
  • Tester sur mobile — le box model se comporte différemment sur petit écran.
Situation Recommandation
Espace entre éléments gap (flex/grid) ou margin
Espace interne (avec fond) padding
Centrage horizontal margin: 0 auto + max-width
Centrage vertical display: flex; align-items: center
Centrage complet display: grid; place-items: center
Conteneur responsive width: 100%; max-width: 1200px
Ratio vidéo aspect-ratio: 16/9
Éviter le débordement overflow: hidden ou clip
Scroll au besoin overflow: auto
Éviter le collapsing display: flex, grid, ou overflow: auto

7. Mini-défi

Exercice 1 : border-box

Écris un bloc qui fait exactement 300px de large avec 25px de padding et 3px de bordure :

  • Avec content-box — quelle est la taille totale ?
  • Avec border-box — quelle est la taille totale ?

Solution :

/* content-box : 300 + 25×2 + 3×2 = 356px */
.content-box-demo {
  box-sizing: content-box;
  width: 300px;
  padding: 25px;
  border: 3px solid #333;
}

/* border-box : 300px total */
.border-box-demo {
  box-sizing: border-box;
  width: 300px;
  padding: 25px;
  border: 3px solid #333;
}

Exercice 2 : Margin collapsing

Explique pourquoi l'espace entre ces deux blocs est de 30px et non 50px, puis propose une solution pour obtenir 50px :

.bloc-1 { margin-bottom: 30px; }
.bloc-2 { margin-top: 20px; }

Solution :

/* Le margin collapsing fusionne les marges verticales */
/* La marge résultante = max(30, 20) = 30px */

/* Solution 1 : Utiliser gap */
.parent {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Solution 2 : Utiliser padding sur le parent */
.parent {
  padding-top: 20px;
}
.bloc-1 { margin-bottom: 30px; }
.bloc-2 { margin-top: 0; }

/* Solution 3 : overflow: auto sur le parent */
.parent {
  overflow: auto;
}

Exercice 3 : Centrage

Centre un bloc de 200×200px au centre exact de son parent (horizontalement ET verticalement) en utilisant 3 méthodes différentes :

Solution :

/* Méthode 1 : Flexbox */
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

/* Méthode 2 : Grid */
.parent {
  display: grid;
  place-items: center;
  height: 100vh;
}

/* Méthode 3 : Margin auto + padding */
.parent {
  display: flex;
  height: 100vh;
}
.enfant {
  width: 200px;
  height: 200px;
  margin: auto;
}

Exercice 4 : Aspect ratio

Crée un conteneur vidéo responsive avec :

  • Largeur 100%
  • Ratio 16:9
  • Une couleur de fond pour simuler la vidéo
  • Un texte centré

Solution :

.video {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #1e293b;
  display: grid;
  place-items: center;
  color: white;
  border-radius: 8px;
}

Exercice 5 : Carte avec padding

Crée une carte avec :

  • Padding : 1.5rem
  • Bordure : 2px solid #e2e8f0
  • Border-radius : 12px
  • Un titre avec margin-bottom: 0.5rem
  • Du texte avec line-height: 1.6
  • Un bouton avec margin-top: 1rem
  • Largeur : fit-content

Solution :

.carte {
  width: fit-content;
  padding: 1.5rem;
  border: 2px solid #e2e8f0;
  border-radius: 12px;
}

.carte h3 {
  margin-bottom: 0.5rem;
}

.carte p {
  line-height: 1.6;
}

.carte button {
  margin-top: 1rem;
  padding: 0.5rem 1rem;
  background: #2563eb;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}

Exercice 6 : Overflow

Crée un bloc de 300×150px avec :

  • Beaucoup de texte qui dépasse
  • Scroll vertical uniquement
  • Pas de scroll horizontal
  • Un padding de 1rem

Solution :

.texte-scroll {
  width: 300px;
  height: 150px;
  padding: 1rem;
  overflow-x: hidden;
  overflow-y: auto;
  border: 1px solid #ccc;
}

8. Projet d'application

Projet : Layout complet avec le Box Model

Crée un fichier index.html et layout.css qui implémentent une page complète en utilisant uniquement les propriétés du Box Model :

HTML requis :

  • Un <header> avec class="en-tete" — contient un <h1> et un <p>
  • Un <main> avec class="conteneur" — contient :
  • Un <aside> avec class="sidebar" — contient une <nav> avec 3 liens
  • Un <article> avec class="contenu" — contient 2 <section>
  • Chaque section contient un <h2>, un <p> et un <a>
  • Un <footer> avec class="pied"

CSS requis :

  • Reset : * avec box-sizing: border-box et margin: 0
  • .en-tete : padding 2rem, border-bottom 3px solid, background color
  • .conteneur : display flex, gap 2rem, max-width 1000px, margin auto, padding 1rem
  • .sidebar : flex 0 0 250px, padding 1.5rem, border-radius 8px, border 1px
  • .contenu : flex 1, display flex, flex-direction column, gap 1.5rem
  • section : padding 1.5rem, border-radius 8px, border 1px
  • .pied : padding 1.5rem, text-align center, border-top 2px solid, margin-top 2rem
  • Media query mobile : .conteneur passe en flex-direction: column

Objectif : Démontrer la maîtrise du Box Model (padding, margin, border, box-sizing, flex, gap) dans un cas réel.

9. Révision

Quiz rapide

  1. Quelles sont les 4 zones du Box Model, de l'intérieur vers l'extérieur ?
  2. Quelle est la différence entre content-box et border-box ?
  3. Pourquoi recommande-t-on border-box sur tous les éléments ?
  4. Que se passe-t-il quand deux marges verticales se touchent ?
  5. Quelle est la shorthand correcte pour margin: 10px 20px 30px 40px ?
  6. Quelle propriété CSS permet de centrer un élément horizontalement ?
  7. Quelle est la différence entre padding et margin ?
  8. Quelle valeur de overflow affiche des barres de défilement uniquement si nécessaire ?
  9. Quelle propriété moderne remplace le padding-top hack pour les ratios vidéo ?
  10. Quelle est la différence entre outline et border ?
Réponses :
  1. Contenu (Content), Padding (Rembourrage), Border (Bordure), Margin (Marge)
  2. content-box : la width ne contient que le contenu. border-box : la width contient contenu + padding + border.
  3. Parce que la largeur correspond à ce qu'on voit à l'écran, ce qui rend les calculs et les pourcentages intuitifs.
  4. Elles fusionnent (margin collapsing) en prenant la plus grande des deux valeurs.
  5. haut (10px), droite (20px), bas (30px), gauche (40px) — sens horaire.
  6. margin-left: auto; margin-right: auto; (ou margin: 0 auto avec une width).
  7. Le padding est intérieur (entre contenu et bordure), le margin est extérieur (entre boîtes).
  8. overflow: auto
  9. aspect-ratio
  10. L'outline ne prend pas de place dans le modèle de boîte, ne suit pas le border-radius, et ne supporte pas les côtés individuels.