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.

C'est quoi la fusion de marge en CSS ?

La zone de marge est l’espace à l’extérieur de la bordure d’un élément.

Prenons cet élément .box, par exemple

<div class="box">
  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
</div>
.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“.

C'est quoi la fusion de marge en CSS ?

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)

C'est quoi la fusion de marge en CSS ?

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 :

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.

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.

C'est quoi la fusion de marge en CSS ?

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.

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.

<section>
<div>Ce paragraphe est avant l'élémént vide.</div>
<div class="empty"><!-- Empty element --></div>
<div>Ce paragraphe est après l'élémént vide.</div>
</section>
section{
  width:300px;
  margin:2rem auto;
}
div:not(.empty){
  border:1px solid;
  text-align:center
}
.empty {
  margin-bottom: 50px;
  margin-top: 50px;
}
C'est quoi la fusion de marge en CSS ?

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.

C'est quoi la fusion de marge en CSS ?

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.

Pour en savoir plus sur display : flow-root, lisez l’article de Rachel AndrewUnderstanding 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.

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.

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.
Catégories : html/css

siddhy

Développeur web full stack depuis une 15aine d'année dans une agence web du sud de la France et Geek depuis toujours, l'apprentissage et le partage font parti intégrante de ma philosophie au même titre que l'évolution personnelle et la sagesse bouddhiste.

0 commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *