C’est quoi la fusion de marge en CSS ?
Les marges en CSS semblent assez simples à première vue : Appliquées à un élément, elles forment un espace autour de lui en repoussant les autres éléments. Cependant il y a quelques subtilités qu’il faut noter pour les marges CSS
Une marge semble être une chose assez simple, cependant, dans cet article, nous allons examiner certaines des choses qui font trébucher les gens en ce qui concerne l’utilisation des marges. En particulier, nous examinerons comment les marges interagissent les unes avec les autres et comment la fusion des marges (ou Collapsing Margins) fonctionne réellement. En complément vous pouvez aussi jeter un oeil à mon article sur l’alignement vertical et horizontal des blocs en css.
Qu’est ce que le modèle de boîte CSS
Avant d’entrer dans le fonctionnement de la fusion des marges, nous devons revoir le modèle de la boîte. Chaque élément de l’arbre de documents est une boîte rectangulaire composée de quatre zones : la zone de contenu, la zone de remplissage (padding), la zone de bordure et la zone de marge. En CSS1, le modèle de boîte a été détaillé avec le diagramme d’art ASCII montré dans l’image ci-dessous.

La zone de marge est l’espace à l’extérieur de la bordure d’un élément.
Prenons cet élément .box
, par exemple
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam molestie fermentum justo, at ornare lacus. Pellentesque quam justo, euismod nec velit ut, blandit venenatis felis
.box { width: 300px; height: 300px; padding: 50px; /* padding area */ margin: 50px; /* margin area */ border: 50px solid black; /* border area */ }
La zone de marge est l’espace à l’extérieur de la bordure. Bien qu’il ne fasse pas strictement partie de l’élément lui-même, il est inclus lorsqu’on considère combien d’espace sur la page est occupé par l’élément. Son contour est appelé “margin edge
” ou “outer edge
“.

Il existe maintenant une spécification de niveau 3 du modèle de boîte en tant qu’ébauche de travail. Cette spécification renvoie à CSS2 pour les définitions du modèle de boîte et des marges.
Qu’est ce que la fusion de marge CSS
Avant de parler de fusion de marge (Collapsing Margins) et de ce que c’est, mettons une chose au clair : un seul type de marge peut fusionner : les marges verticales (haut et bas). La fusion de marge CSS ne s’applique jamais aux marges horizontales (gauche et droite).
Donc une marge fusionnée est ce qui se produit lorsque deux éléments de niveau bloc avec des marges verticales se combinent. Lorsque cela se produit, la plus grande des deux marges est supposée être la marge unique fusionnée. La plus petite marge se retrouve essentiellement à l’intérieur de la plus grande.
Par exemple, nous avons deux éléments; l’élément A a une marge inférieure de 10px et l’élément B a une marge supérieure de 30px. Si nous plaçons ces deux éléments de type bloc l’un après l’autre, la marge entre les deux éléments est combinée et la marge fusionnée résultante est de 30px. (Note : Si les marges de l’élément A et de l’élément B étaient les mêmes, disons 30px chacune, la marge résultante serait de 30px)

Certains pourraient se demander : qu’en est-il des marges négatives ? La réponse est que cela a un impact significatif et réduit la marge entre les deux éléments.
50px + (-25px) = 25px
En clair, si une marge est négative, la marge négative est soustraite de la marge positive, réduisant ainsi la marge verticale totale.
Les marges fusionnent dans les situations suivantes :
- Parent et premier ou dernier élément enfant
- Les frères et sœurs adjacents
- Boîtes complètement vides
Examinons chacun de ces scénarios à tour de rôle, avant d’examiner les éléments qui empêchent les marges de fusionner dans ces scénarios.
Fusion de marge des éléments parents avec leur 1er ou dernier élément enfant
Si une marge supérieure est appliquée à un élément parent ainsi qu’à son premier enfant entrant, les marges seront fusionnées. De la même manière la fusion de marge apparaîtra si une marge inférieure est appliquée à un élément parent ainsi qu’à son dernier enfant.
C’est le scénario de fusion de marge qui surprend le plus souvent les gens, car il ne semble pas particulièrement intuitif. Dans le CodePen suivant, j’ai une div
avec une classe wrapper, et j’ai donné à cette div
un outline
en rouge pour que vous puissiez voir où il est. Les trois éléments enfants ont tous une marge de 50 pixels. Cependant, le premier et le dernier éléments sont à fleur avec les bords du wrapper; il n’y a pas de marge de 50 pixels entre l’élément et le wrapper.
https://codepen.io/Siddhyn/embed/jgzoyx/?height=265&theme-id=0&default-tab=result
C’est parce que la marge sur l’enfant fusionne avec n’importe quelle marge sur le parent et finit donc à l’extérieur du parent. Vous pouvez le voir si vous inspectez le premier enfant à l’aide de l’outil de développement Chrome. La zone jaune surlignée est la marge.

Fusion de marge css des éléments adjacents
Ma description initiale de la fusion des marges est celle la fusion des marges entre frères et sœurs adjacents. Sauf dans les situations mentionnées ci-dessous, si vous avez deux éléments qui s’affichent l’un après l’autre dans le flux normal, la marge inférieure du premier élément fusionne avec la marge supérieure de l’élément suivant.
Dans l’exemple CodePen ci-dessous, il y a trois éléments div. La première a une marge supérieure et inférieure de 50 pixels. La seconde a une marge supérieure et inférieure de 20px. La troisième a une marge supérieure et inférieure de 3em. La marge entre les deux premiers éléments est de 50 pixels, car la plus petite marge supérieure est combinée avec la plus grande marge inférieure. La marge entre les deux deuxièmes éléments dans 3em, comme 3em est plus grande que les 20 pixels sur le bas du deuxième élément.
https://codepen.io/Siddhyn/embed/eqMowL/?height=265&theme-id=0&default-tab=result
Cas des boites complètement vides
Enfin, les marges supérieure et inférieure d’un seul élément peuvent fusionner si l’élément a une hauteur calculée de 0, c’est-à-dire s’il s’agit d’un élément vide.
Ce paragraphe est avant l'élémént vide. Ce paragraphe est après l'élémént vide.
section{ width:300px; margin:2rem auto; } div:not(.empty){ border:1px solid; text-align:center } .empty { margin-bottom: 50px; margin-top: 50px; }

Dans l’exemple précédent, l’élément avec une classe .empty
a une marge supérieure et inférieure de 50 pixels, cependant, l’espace entre le premier et le troisième élément n’est pas de 100 pixels, mais 50. Ceci est dû à la fusion des deux marges. Si vous ajoutez quoi que ce soit à cette boîte (même du rembourrage), les marges supérieure et inférieure seront utilisées et ne fusionneront pas.
Les exceptions de fusion de marge css
Comme pour tout, il y a quelques exceptions à noter pour les cas où les marges ne s’effondreront pas.
Flexbox, Grid, et autres éléments de type non-bloc
La fusion de marge ne s’appliquent qu’aux éléments de type bloc
. Il s’agit d’éléments qui ont l’une des valeurs suivantes pour la propriété d’affichage : bloc
, list-item
ou table
. Par conséquent, les éléments flexibles, les éléments de grille, les éléments positionnés de façon absolue et les autres éléments de type non-bloc n’ont pas de fusion de marge.
L’élément racine (root)
Les marges de la boîte de l’élément racine ne fusionnent jamais.
Les boites en ligne, flottants, padding et bordures
Dans les cas d’exemple mentionnés ci-dessus, la fusion de marge ne se produira pas s’il y a des boites en lignes, des boites flottantes, des paddings ou des bordures qui se trouvent entre les deux éléments.
Prenons l’exemple où la marge supérieure du parent est réduite avec la marge supérieure de son premier enfant. Si nous ajoutons une bordure autour de l’élément parent, les marges ne fusionnent plus.

Création d’un contexte de formatage en bloc
Un nouveau Contexte de Formatage de Bloc (BFC en anglais) empêchera également la fusion de la marge à travers l’élément contenant. Si l’on reprend l’exemple du premier et du dernier enfant, qui finissent avec leurs marges à l’extérieur du wrapper, et si on donne au wrapper un display:flow-root
, créant ainsi une nouvelle BFC, les marges restent à l’intérieur.
https://codepen.io/Siddhyn/embed/MNVdBR/?height=265&theme-id=0&default-tab=result
Pour en savoir plus sur display : flow-root
, lisez l’article de Rachel Andrew “Understanding CSS Layout And The Block Formatting Context“. Changer la valeur de la propriété overflow
à auto
aura le même effet, car cela crée aussi un nouveau BFC, bien qu’il puisse aussi créer des barres de défilement que vous ne vouliez pas dans certains scénarios.
La fusion de marge pour les conteneurs Flex
et Grid
Les conteneurs Flex et Grid établissent des contextes de formatage Flex et Grid pour leurs enfants, ils ont donc des comportements différents pour bloquer la mise en page. L’une de ces différences est que les marges ne fusionnent pas :
“Un conteneur flex établit un nouveau contexte de mise en forme flex pour son contenu. C’est la même chose que d’établir un contexte de formatage de bloc, sauf que la mise en page flexible est utilisée à la place de la mise en page de bloc. Par exemple, les flotteurs ne s’immiscent pas dans le conteneur flexible, et les marges du conteneur flexible ne fusionnent pas avec les marges de son contenu.”
Flexbox Level 1 W3C
Si nous prenons l’exemple ci-dessus et faisons l’emballage dans un conteneur flex, en affichant les articles avec flex-direction: column
, vous pouvez voir que les marges sont maintenant contenues par l’emballage. De plus, les marges entre les éléments de flex adjacents ne fusionnent pas les unes avec les autres, ce qui fait que nous obtenons 100 pixels entre les éléments de flex, soit le total des 50 pixels en haut et en bas des éléments.
https://codepen.io/Siddhyn/embed/RXYbyb/?height=265&theme-id=0&default-tab=result
En supplément : Les marges CSS dans un flux relatif
Nous avons parlé des marges verticales tout au long de cet article, cependant, les CSS modernes ont tendance à penser les choses d’une manière relative plutôt que absolue. Par conséquent, lorsque nous parlons de marges verticales, nous parlons vraiment de marges dans la dimension du bloc. Ces marges seront en haut et en bas si nous sommes dans un mode d’écriture horizontale, mais elles seront à droite et à gauche dans un mode d’écriture verticale écrit de gauche à droite.
Une fois que l’on travaille avec des directions logiques et relatives de flux, il devient plus facile de parler de début et de fin de bloc, plutôt que de haut en bas. Pour faciliter cela, CSS a introduit la spécification Propriétés logiques et valeurs. Ces cartes présentent les propriétés relatives sur les propriétés physiques.
Pour les marges, cela nous donne les mappages suivants (si nous travaillons en écriture horizontale avec une direction de texte de gauche à droite).
margin-top
=margin-block-start
margin-right
=margin-inline-end
margin-bottom
=margin-block-end
margin-left
=margin-inline-start
Nous avons également deux nouveaux raccourcis qui permettent de régler les deux blocs en même temps ou les deux en ligne.
margin-block
margin-inline
Dans l’exemple CodePen suivant, j’ai utilisé ces mots-clés relatifs de flux et ensuite changé le mode d’écriture de la boîte, vous pouvez voir comment les marges suivent la direction du texte plutôt que d’être lié au haut physique, à droite, en bas et à gauche.
https://codepen.io/Siddhyn/embed/PMdwOx/?height=265&theme-id=0&default-tab=result
Vous pouvez en savoir plus sur les propriétés logiques et les valeurs sur MDN
En conclusion
Les fusions de marge en CSS peuvent être pénibles si vous ne comprenez pas bien quand elles se produisent. La première étape pour les traiter ou les éviter est de comprendre exactement à quel cas de fusion de marge nous avons affaire.
Les fusions de marge qui se produisent à cause d’éléments vides ou de relations parents/enfants ne peuvent pas vraiment être évitées. La seule façon de contrer les fusions de marge qui se produisent de cette façon est d’insérer quelque chose entre les éléments, par exemple une bordure.
Par contre, il est possible d’éviter la fusion des marges dû à la présence d’éléments frères et sœurs adjacents en modifiant le style d’écriture CSS. Personnellement, je préfère suivre la règle de Harry Roberts sur les déclarations de marge dans une seule direction, qui a d’autres avantages que celui d’aider à éviter la fusion des marges.
Vous savez maintenant tout ce qu’il y a à savoir sur les marges ! En bref :
- La fusion des marges est une chose. Comprendre pourquoi cela se produit et quand cela ne se produit pas vous aidera à résoudre tous les problèmes qu’il peut causer.
- Fixer les marges dans une seule direction résout de nombreux maux de tête liés aux marges.
- Comme pour tout ce qui est en CSS, partagez avec votre équipe les décisions que vous prenez et commentez votre code.
- Penser aux dimensions en bloc et en ligne plutôt qu’aux dimensions physiques en haut, à droite, en bas et à gauche vous aidera à mesure que le web évolue vers un mode d’écriture agnostique.