Marge vs padding : les règles système
Un développeur empile une carte au-dessus d’un titre. La carte a
margin-bottom: 24px, le titre a margin-top: 16px, donc l’espace devrait
être de 40px. Le navigateur affiche 24. Aucune erreur, aucun avertissement —
la marge de 16px a tout simplement disparu, absorbée par un comportement CSS
appelé fusion des marges (margin collapsing) que la plupart des gens
découvrent exactement de cette façon : comme un espace mystérieux qui ne
correspond à l’arithmétique d’aucun des deux éléments.
Le padding est l’espace à l’intérieur de la bordure d’un élément ; la marge est l’espace à l’extérieur. La règle qui garde un design system composable va un cran plus loin : le padding appartient au composant — il fait partie de ce que le composant est — tandis que la marge appartient à la mise en page — une affirmation sur l’endroit où le composant se trouve placé. Un bouton possède son padding comme il possède son rayon de bordure ; il ne devrait avoir aucun avis sur sa distance aux voisins.
Cet article couvre la définition du modèle de boîte, la règle de propriété qui
compte plus que la définition, le comportement de fusion derrière les 16px
disparus, et le motif du gap géré par le parent qui contourne entièrement la
fusion — avec chaque distance tirée de la même échelle
d’espacement.
Quelle est la différence entre marge et padding en CSS ?
Dans le
modèle de boîte CSS,
chaque élément est un ensemble de rectangles imbriqués : le contenu, puis le
padding, puis la bordure, puis la marge. Le padding se trouve à l’intérieur de
la bordure, il prend donc la couleur de fond de l’élément, étend sa zone
cliquable et — avec box-sizing: border-box — compte dans la largeur déclarée
de l’élément. La marge se trouve à l’extérieur de la bordure : toujours
transparente, jamais cliquable, et, dans les empilements verticaux, capable de
fusionner avec les marges voisines.
Une façon compacte de retenir la distinction : le padding change l’apparence de l’élément ; la marge change la façon dont il se rapporte à tout ce qui l’entoure. C’est cette asymétrie qui fait que les deux méritent des propriétaires différents.
Quand utiliser la marge, et quand le padding ?
Prenez un bouton. Son padding — disons 11px en vertical, 16px en horizontal —
fait partie de son identité : c’est ce qui donne l’impression que le bouton est
le même dans une barre d’outils, un formulaire et une boîte de dialogue. Sa
distance à l’élément suivant ne fait pas partie de son identité. Dans une barre
d’outils dense, le bon espace pourrait être de 8px ; entre des champs de
formulaire, 16px ; sous un paragraphe d’introduction, 32px. Si le bouton est
livré avec margin-right: 16px, il est correct à l’un de ces endroits et faux
aux autres — et chaque mauvais endroit engendre une surcharge. Multipliez par
cinquante composants et la feuille de style devient une dispute entre composants
au sujet d’un espace qu’aucun d’eux ne devrait posséder.
D’où la règle système : les composants définissent leur padding et jamais leurs marges extérieures ; les conteneurs définissent les distances entre leurs enfants. N’importe quel composant peut alors être déposé dans n’importe quelle mise en page sans négociation — ce qui recouvre l’essentiel de ce que « composable » signifie pour l’espacement.
Voyez les deux rôles sur une même échelle dans Scale Composer — les petits pas (8, 11, 16) font le travail intérieur en tant que padding de composant, tandis que les pas plus grands (16, 23, 32, 45) font le travail extérieur en tant qu’espaces de mise en page, tous générés à partir d’une seule base et d’un seul ratio.

Pourquoi les marges verticales fusionnent-elles ?
Quand deux éléments de bloc s’empilent dans le flux normal du document, leurs marges verticales adjacentes ne s’additionnent pas — elles fusionnent en une seule marge égale à la plus grande des deux :
| Marge sous l’élément A | Marge au-dessus de l’élément B | Espace attendu | Espace affiché |
|---|---|---|---|
| 24px | 16px | 40px | 24px |
| 16px | 16px | 32px | 16px |
| 24px | 24px | 48px | 24px |
Ce comportement est délibéré. CSS a été conçu pour des documents, où les paragraphes portent une marge au-dessus et en dessous ; si ces marges s’additionnaient, chaque paire de paragraphes serait à double interligne. La fusion vers la plus grande valeur donne au texte courant un rythme régulier, gratuitement. Dans la mise en page d’application, le même comportement se lit comme un bug : deux valeurs explicites produisent une troisième valeur qui n’apparaît dans aucune feuille de style. Il a aussi des variantes moins connues — la marge supérieure d’un enfant peut fusionner à travers le bord de son parent et pousser tout le conteneur du parent vers le bas — ce qui explique pourquoi « d’où vient cet espace ? » reste un genre de débogage aussi durable.
Deux limites utiles : les marges horizontales ne fusionnent jamais, et les enfants des conteneurs flex et grid ne fusionnent jamais dans aucune direction.
Que faut-il utiliser à la place des marges entre éléments frères ?
Donnez l’espace au parent. Les conteneurs flex et grid ont une propriété gap
qui place une distance fixe entre les enfants — pas de fusion, pas d’exceptions
pour le premier et le dernier enfant, pas d’avis de composant :
.stack {
display: flex;
flex-direction: column;
gap: 16px; /* entre les enfants */
padding: 23px; /* entre les enfants et le bord du conteneur */
}
La division du travail devient nette : le padding du conteneur gère la distance
entre son bord et son contenu, le gap gère les distances entre les enfants,
et chaque enfant ne gère que son propre padding. Chaque distance à l’écran a
exactement un propriétaire, et la classe de bugs de l’espace mystérieux perd
son habitat.
Les marges ne quittent pas complètement la boîte à outils.
La prose est l’exception permanente :
la bonne distance dépend alors de la paire — titre-à-paragraphe diffère de
paragraphe-à-paragraphe — et le gap uniforme d’un conteneur ne peut pas varier
selon la paire. Entre composants, en revanche, le gap géré par le parent est le
motif vers lequel la plupart des mises en page modernes ont convergé.
Marge, padding et gap doivent-ils partager une seule échelle ?
Oui — c’est la même décision de conception (à quelle distance les choses se trouvent-elles ?) détenue par des propriétaires différents, ils devraient donc puiser dans le même court menu. Une échelle d’espacement générée à partir d’une base de 16px, d’un ratio 2 et de deux notes par doublement donne 8, 11, 16, 23, 32, 45, 64 : le bas de l’échelle couvre le padding à l’intérieur des composants compacts, le milieu couvre les espaces entre éléments, et le haut couvre les sections. Quand les distances intérieures et extérieures viennent d’une seule échelle, le padding d’une carte et l’espace entre les cartes restent proportionnels même si des propriétaires différents les définissent.
Qui possède chaque distance à l’échelle de la page ?
La règle de propriété se révèle le plus visiblement sur une page entière, où des dizaines d’espaces seraient sinon des dizaines de décisions locales. Les gouttières sont l’idée du gap géré par le parent appliquée à toute la mise en page : les colonnes ne possèdent pas leurs distances, la grille le fait — 4 colonnes sur mobile, 8 sur tablette, 12 sur desktop, chaque gouttière et chaque marge étant un pas de la même échelle. Quand vous pouvez nommer le propriétaire de chaque distance sur la page, la question marge-vs-padding s’est répondue d’elle-même : faites défiler les gouttières et les marges le long de cette échelle dans la vue grille.