web-dev-qa-db-fra.com

Comment désactiver la réduction de marge?

Existe-t-il un moyen de désactiver complètement la réduction de la marge? Les seules solutions que j'ai trouvées (sous le nom de "uncollapsing") impliquent l'utilisation d'une bordure de 1px ou d'un remplissage de 1px. Je trouve cela inacceptable: le pixel parasite complique les calculs sans raison valable. Existe-t-il un moyen plus raisonnable de désactiver cette réduction de marge?

151
kjo

Il existe deux principaux types d'effondrement des marges:

  • Réduire les marges entre les éléments adjacents
  • Réduction des marges entre les éléments parents et enfants

L'utilisation d'un remplissage ou d'une bordure empêchera la réduction uniquement dans ce dernier cas. De même, toute valeur de overflow différente de sa valeur par défaut (visible) appliquée au parent empêchera l’effondrement. Ainsi, overflow: auto et overflow: hidden auront le même effet. Peut-être que la seule différence en utilisant hidden est la conséquence involontaire de cacher du contenu si le parent a une hauteur fixe.

Les autres propriétés qui, une fois appliquées au parent, peuvent aider à résoudre ce problème sont les suivantes:

  • float: left / right
  • position: absolute
  • display: inline-block

Vous pouvez tous les tester ici: http://jsfiddle.net/XB9wX/1/ .

Je devrais ajouter que, comme d'habitude, Internet Explorer est l'exception. Plus spécifiquement, dans IE 7, les marges ne sont pas réduites lorsqu'un type de présentation est spécifié pour l'élément parent, tel que width

Sources: article de Sitepoint Collapsing Margins

202
hqcasanova

Vous pouvez également utiliser le bon vieux micro clearfix pour cela.

#container:before, #container:after{
    content: ' ';
    display: table;
}

Voir le violon mis à jour: http://jsfiddle.net/XB9wX/97/

48
Blackgrid

Une astuce intéressante pour désactiver le regroupement des marges qui n'a pas d'impact visuel, pour autant que je sache, consiste à définir le remplissage du parent sur 0.05px:

.parentClass {
    padding: 0.05px;
}

Le remplissage n'est plus 0, donc le repliement ne se produira plus, mais en même temps, le remplissage est suffisamment petit pour qu'il soit arrondi à 0. 

Si un autre remplissage est souhaité, appliquez-le uniquement à la "direction" dans laquelle le regroupement des marges n'est pas souhaité, par exemple padding-top: 0.05px;.

Exemple de travail:

.noCollapse {
  padding: 0.05px;
}

.parent {
  background-color: red;
  width: 150px;
}

.children {
  margin-top: 50px;

  background-color: Lime;      
  width: 100px;
  height: 100px;
}
<h3>Border collapsing</h3>
<div class="parent">
  <div class="children">
  </div>
</div>

<h3>No border collapsing</h3>
<div class="parent noCollapse">
  <div class="children">
  </div>
</div>

Edit: a changé la valeur de 0.1 à 0.05. Comme Chris Morgan l'a mentionné dans un commentaire ci-dessous, et de ce petit test , il semblerait qu'en fait, Firefox prenne en compte le remplissage 0.1px. Cependant, 0.05px semble faire l'affaire.

39
Nicu Surdu

overflow:hidden empêche de réduire les marges, mais il n’est pas exempt d’effets secondaires - c’est-à-dire que ... cache le débordement.

En dehors de cela et de ce que vous avez mentionné, vous devez juste apprendre à vivre avec et à apprendre pour ce jour où ils sont réellement utiles (tous les 3 à 5 ans).

20
Litek

Chaque navigateur Webkit doit prendre en charge les propriétés -webkit-margin-collapse. Il existe également des sous-propriétés pour ne le définir que pour la marge supérieure ou inférieure. Vous pouvez lui donner les valeurs replier (par défaut), rejeter (définit la marge sur 0 s'il existe une marge voisine) et séparer (empêche la réduction de la marge).

J'ai testé que cela fonctionne sur les versions 2014 de Chrome et Safari. Malheureusement, je ne pense pas que cela serait supporté dans IE car ce n'est pas basé sur webkit.

Lisez Référence CSS Safari d’Apple pour une explication complète.

Si vous vérifiez la page des extensions du kit Web CSS de Mozilla , ils répertorient ces propriétés comme étant propriétaires et vous déconseillent de les utiliser. En effet, ils ne seront probablement pas prochainement intégrés au CSS standard et seuls les navigateurs Webkit les prendront en charge.

8
Dan Carter

Je sais que c'est un très vieux billet, mais je voulais juste dire que l'utilisation de flexbox sur un élément parent désactiverait le regroupement des marges pour ses éléments enfants.

6
Genzo

En fait, il y en a un qui fonctionne parfaitement:

affichage: flex; flex-direction: colonne;

aussi longtemps que vous pouvez vivre avec seulement IE10 et plus

.container {
  display: flex;
  flex-direction: column;
    background: #ddd;
    width: 15em;
}

.square {
    margin: 15px;
    height: 3em;
    background: yellow;
}
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>

3
Daniel Koster

J'ai eu un problème similaire avec l'effondrement de la marge parce que le parent avait position défini sur relatif. Voici la liste des commandes que vous pouvez utiliser pour désactiver le regroupement des marges. 

ICI IS TERRAIN DE JEU À TESTER

Essayez simplement d’affecter l’élément parent-fix* à l’élément div.container ou toute classe children-fix* à div.margin. Choisissez celui qui correspond le mieux à vos besoins.

Quand

  • margin collapsing est disabled, div.absolute avec un arrière-plan rouge sera placé tout en haut de la page.
  • margin est en train de réduirediv.absolute sera positionné à la même coordonnée Y que div.margin

html, body { margin: 0; padding: 0; }

.container {
  width: 100%;
  position: relative;
}

.absolute {
  position: absolute;
  top: 0;
  left: 50px;
  right: 50px;
  height: 100px;
  border: 5px solid #F00;
  background-color: rgba(255, 0, 0, 0.5);
}

.margin {
  width: 100%;
  height: 20px;
  background-color: #444;
  margin-top: 50px;
  color: #FFF;
}

/* Here are some examples on how to disable margin 
   collapsing from within parent (.container) */
.parent-fix1 { padding-top: 1px; }
.parent-fix2 { border: 1px solid rgba(0,0,0, 0);}
.parent-fix3 { overflow: auto;}
.parent-fix4 { float: left;}
.parent-fix5 { display: inline-block; }
.parent-fix6 { position: absolute; }
.parent-fix7 { display: flex; }
.parent-fix8 { -webkit-margin-collapse: separate; }
.parent-fix9:before {  content: ' '; display: table; }

/* Here are some examples on how to disable margin 
   collapsing from within children (.margin) */
.children-fix1 { float: left; }
.children-fix2 { display: inline-block; }
<div class="container parent-fix1">
  <div class="margin children-fix">margin</div>
  <div class="absolute"></div>
</div>

Voici jsFiddle avec un exemple que vous pouvez éditer

2
Buksy

Pour votre information, vous pouvez utiliser Grid mais avec des effets secondaires :)

.parent {
  display: grid
}
0
Whisher