frontend / css
Box model
Explication
Ce que vous allez apprendre
- Identifier les quatre couches du box model : contenu, padding, bordure, marge
- Comprendre pourquoi
widthne correspond pas toujours à la largeur réellement affichée - Appliquer
box-sizing: border-boxpour rendre les dimensions prévisibles - Reconnaître le phénomène de fusion de marges (margin collapsing) et savoir quand il ne s'applique pas
- Distinguer
outlinedeborderdans leur impact sur la mise en page
Dans quel contexte ?
Un développeur fixe width: 300px sur une carte produit .carte-produit dans boutique.css, avec padding: 20px et border: 5px solid. En comparant avec la maquette Figma, la carte affichée s'avère 50px plus large que prévu, cassant l'alignement de la grille de trois colonnes. La cause : sans box-sizing: border-box, le padding et la bordure s'ajoutent PAR-DESSUS les 300px au lieu d'être inclus dedans.
Étape 1 : tout élément est une boîte
C'est l'un des concepts les plus fondamentaux de CSS : chaque élément HTML, quel que soit son contenu, est traité par le navigateur comme une boîte rectangulaire. Retenez bien cette image avant tout le reste.
Étape 2 : quatre couches imbriquées
Cette boîte est composée de quatre couches, comme des poupées russes : le contenu au centre, entouré du padding (l'espace intérieur), puis de la bordure, puis enfin de la marge (l'espace extérieur qui la sépare des autres boîtes).
Étape 3 : le piège qui déroute tout le monde
Voici le premier piège classique. Par défaut, fixer width: 300px sur un élément ne concerne QUE le contenu : le padding et la bordure s'ajoutent PAR-DESSUS, rendant la boîte réellement affichée plus large que prévu.
Étape 4 : la solution devenue quasi universelle
Voici comment on corrige ça : box-sizing: border-box, appliqué globalement dès le début du projet, change la règle du jeu pour que width inclue désormais le padding et la bordure. Les dimensions deviennent enfin prévisibles, ce qui explique pourquoi cette ligne apparaît en tête de presque tous les projets CSS modernes.
box-sizing | width inclut... | Largeur réelle si width:300px; padding:20px; border:5px |
|---|---|---|
content-box (défaut) | Le contenu seul | 350px (300 + 40 padding + 10 border) |
border-box | Contenu + padding + bordure | 300px exactement |
Bonne pratique
Placez * { box-sizing: border-box; } tout en haut de votre feuille de style, dès le début du projet. C'est l'une des rares règles CSS qui font consensus sur pratiquement tous les projets modernes.
Étape 5 : un second piège, la fusion de marges
Il reste un autre comportement surprenant à connaître. Quand deux blocs empilés verticalement ont chacun une marge (l'un en bas, l'autre en haut), l'espace final entre eux n'est PAS la somme des deux marges, mais seulement la plus grande des deux — un phénomène appelé "margin collapsing", qui existe depuis les débuts de CSS.
Piège fréquent
.bloc-1 { margin-bottom: 30px; } suivi de .bloc-2 { margin-top: 20px; } ne produit pas 50px d'espace entre les deux, mais 30px (le maximum des deux). Ce comportement disparaît dès que l'un des deux parents est un conteneur flex ou grid : bon réflexe à garder si l'espacement semble incohérent.
Étape 6 : une confusion fréquente, outline vs border
Ces deux propriétés se ressemblent visuellement, mais se comportent très différemment. La bordure occupe de l'espace et pousse le contenu, alors que l'outline se dessine PAR-DESSUS sans jamais rien décaler autour.
Et ensuite ?
C'est justement pour cette raison qu'on utilise outline pour les indicateurs de focus au clavier : elle n'a aucun impact sur la mise en page environnante. Une fois le box model maîtrisé, la prochaine étape consiste à choisir les bonnes unités de mesure et de couleur.
Commandes & code
Box model
Chaque élément est une boîte rectangulaire composée de quatre couches concentriques.
/*
┌─────────────────────────────┐
│ margin │
│ ┌─────────────────────┐ │
│ │ border │ │
│ │ ┌───────────────┐ │ │
│ │ │ padding │ │ │
│ │ │ ┌─────────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └─────────┘ │ │ │
│ │ └───────────────┘ │ │
│ └─────────────────────┘ │
└─────────────────────────────┘
*/
.boite {
width: 300px;
padding: 20px;
border: 5px solid #333;
margin: 10px;
}
/* box-sizing: content-box (défaut) -> largeur RÉELLE affichée =
300 (width) + 40 (padding) + 10 (border) = 350px, hors margin *//* box-sizing: border-box -> width INCLUT padding + border : bien plus prévisible */
* {
box-sizing: border-box;
}
.boite {
width: 300px;
padding: 20px;
border: 5px solid #333;
/* largeur affichée = exactement 300px, content réduit en interne */
}/* Fusion de marges verticales (margin collapsing) : piège classique */
.bloc-1 { margin-bottom: 30px; }
.bloc-2 { margin-top: 20px; }
/* espace RÉEL entre les deux : 30px (le max des deux), pas 50px ! */
/* Ne se produit qu'entre marges verticales de blocs en flux normal.
N'arrive PAS si : flex/grid container, overflow != visible,
padding/border non nul entre les deux, position absolute/fixed. */
/* Raccourcis de padding/margin/border : sens horaire depuis le haut */
.espacements {
padding: 10px; /* les 4 côtés */
padding: 10px 20px; /* vertical horizontal */
padding: 10px 20px 15px; /* haut horizontal bas */
padding: 10px 20px 15px 5px; /* haut droite bas gauche */
/* Logical properties : suivent le sens d'écriture (i18n RTL/LTR) */
padding-inline: 20px; /* gauche+droite en LTR, inversé en RTL */
padding-block: 10px; /* haut+bas */
margin-inline-start: 8px;
}/* outline vs border : outline ne participe PAS au box model, ne décale rien */
.focusable:focus {
outline: 2px solid blue;
outline-offset: 2px; /* espace entre la bordure et l'outline */
}
/* display influence directement le box model */
.inline { display: inline; } /* width/height/margin vertical ignorés */
.block { display: block; } /* respecte tout le box model */
.inline-block { display: inline-block; } /* comme inline, mais respecte width/height */Résumé
box-sizing: border-box(posé globalement) rendwidthprévisible en incluant padding/border.- Les marges verticales fusionnent entre blocs en flux normal : ce n'est pas un bug.
outlinene fait pas partie du box model, contrairement àborder.- Les logical properties (
margin-inline,padding-block...) s'adaptent au sens d'écriture.
Exercices pratiques
Mission : réparer une grille de trois cartes qui déborde
Objectif : Diagnostiquer un débordement de largeur causé par le box model par défaut, puis corriger sans changer les valeurs de width, padding ou border.
Contexte
Sur boutique.css, trois .carte-produit sont posées côte à côte dans un conteneur de 960px avec width: 300px, padding: 20px et border: 5px solid #333 chacune, sans aucune règle box-sizing définie nulle part dans le fichier. La troisième carte passe systématiquement à la ligne suivante, alors que 3 x 300px = 900px devrait largement tenir dans 960px.