web-dev-qa-db-fra.com

Comment fonctionnent les marges négatives dans CSS et pourquoi (margin-top: -5! = Margin-bottom: 5)?

Une astuce courante pour les éléments de positionnement vertical consiste à utiliser les CSS suivants:

.item {
    position:absolute;
    top:50%;
    margin-top:-8px; /* half of height */
    height: 16px;
}

Dans la vue métrique, comme dans Chrome, voici ce que vous voyez:

enter image description here

Cependant, aucune marge visuelle n’est décrite lorsque vous survolez l’élément, c’est-à-dire que la marge se situe "à l’extérieur" de la frontière et peut être visualisée. Mais les marges négatives ne sont pas visibles. Comment sont-ils et qu'est-ce qui le rend différent?

Pourquoi margin-top:-8pxdifférent demargin-bottom:8px?

Alors, comment fonctionnent les marges négatives et quelle est l’intuition qui les sous-tend? Comment font-ils "heurter" (dans le cas de margin-top < 0) un article?

97
PhD

Les marges négatives sont valides en css et la compréhension de leur comportement (conforme) repose principalement sur le modèle de boîte et sur le regroupement des marges. Bien que certains scénarios soient plus complexes, de nombreuses erreurs courantes peuvent être évitées après avoir étudié les spécifications.

Par exemple, le rendu de votre exemple de code est guidé par la spécification css décrite dans la section calcul des hauteurs et des marges pour les éléments non remplacés en position absolue .

Si je devais faire une représentation graphique, j'irais probablement avec quelque chose comme ceci (pas à l'échelle):

negative top margin

La zone de marge a perdu 8px en haut, mais cela n’affecte pas les zones de contenu et de remplissage . Parce que votre élément est parfaitement positionné, le déplacement de l’élément de 8 pixels vers le haut n’entraîne aucune perturbation supplémentaire dans la présentation; avec un contenu statique entrant, ce n'est pas toujours le cas.

Bonus:

Vous avez toujours besoin de convaincre que lire les spécifications est le chemin à parcourir (par opposition à articles comme celui-ci )? Je vois que vous essayez de centrer l'élément verticalement, alors pourquoi devez-vous définir margin-top:-8px; et non margin-top:-50%;?

Eh bien, le centrage vertical en CSS est plus difficile qu'il ne devrait l'être . Lorsque vous définissez même les marges supérieures ou inférieures en%, la valeur est calculée as n pourcentage toujours relatif à la largeur du bloc conteneur . Ceci est plutôt un piège courant et le caprice est rarement décrit en dehors de w3 docos

78
o.v.

Je vais essayer de l'expliquer visuellement:

/**
 * explaining margins
 */

body {
  padding: 3em 15%
}

.parent {
  width: 50%;
  width: 400px;
  height: 400px;
  position: relative;
  background: lemonchiffon;
}

.parent:before,
.parent:after {
  position: absolute;
  content: "";
}

.parent:before {
  top: 0;
  bottom: 0;
  left: 50%;
  border-left: dashed 1px #ccc;
}

.parent:after {
  left: 0;
  right: 0;
  top: 50%;
  border-top: dashed 1px #ccc;
}

.child {
  width: 200px;
  height: 200px;
  background: rgba(200, 198, 133, .5);
}

ul {
  padding: 5% 20px;
}

.set1 .child {
  margin: 0;
  position: relative;
}

.set2 .child {
  margin-left: 75px;
  position: relative;
}

.set3 .child {
  margin-left: -75px;
  position: relative;
}


/* position absolute */

.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}

.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}

.set6 .child {
  top: 50%; /* level from which margin-top starts 
        - downwards, in the case of a positive margin
        - upwards, in the case of a negative margin     
        */
  left: 50%; /* level from which margin-left starts 
        - towards right, in the case of a positive margin
        - towards left, in the case of a negative margin        
        */
  margin: -75px;
  position: absolute;
}
<!-- content to be placed inside <body>…</body> -->
<h2><code>position: relative;</code></h2>
<h3>Set 1</h3>
<div class="parent set 1">
  <div class="child">
    <pre>
.set1 .child {
  margin: 0;
  position: relative;
}
                </pre>
  </div>
</div>

<h3>Set 2</h3>
<div class="parent set2">
  <div class="child">
    <pre>
.set2 .child {
  margin-left: 75px;
  position: relative;
}
                </pre>
  </div>
</div>

<h3>Set 3</h3>
<div class="parent set3">
  <div class="child">
    <pre>
.set3 .child {
  margin-left: -75px;
  position: relative;
}
                </pre>
  </div>
</div>

<h2><code>position: absolute;</code></h2>

<h3>Set 4</h3>
<div class="parent set4">
  <div class="child">
    <pre>
.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}
                </pre>
  </div>
</div>

<h3>Set 5</h3>
<div class="parent set5">
  <div class="child">
    <pre>
.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}
                </pre>
  </div>
</div>

<h3>Set 6</h3>
<div class="parent set6">
  <div class="child">
    <pre>
.set6 .child {
  top: 50%;
  left: 50%;
  margin: -75px;
  position: absolute;
}
                </pre>
  </div>
</div>
70
Ana

La marge est l’espacement à l’extérieur de votre élément, tout comme le rembourrage est l’espace à l’intérieur de votre élément.

La définition de la marge inférieure indique la distance que vous souhaitez au-dessous du bloc actuel. Définir une marge supérieure négative indique que vous souhaitez un espacement négatif au-dessus de votre bloc. L'espacement négatif peut en soi être un concept déroutant, mais la manière dont la marge supérieure positive pousse le contenu vers le bas, une marge supérieure négative le tire vers le haut.

28
David Hedlund

Une marge supérieure de -8px signifie qu'il sera 8px plus élevé que s'il avait 0 marge.

Une marge inférieure de 8px signifie que la chose en dessous sera 8px plus bas que si elle avait 0 marge.

19
Rich Bradshaw

on a déjà fait de bons points ici, mais bien qu’il y ait beaucoup d’informations sur , comment le rendu des marges est effectué par le pourquoi on n'a pas encore tout à fait répondu:

"Pourquoi margin-top: -8px n'est-il pas identique à margin-bottom: 8px?"

ce que nous pourrions aussi demander, c'est:

Pourquoi une marge inférieure positive ne "bloque-t-elle" les éléments précédents, alors qu'une marge supérieure positive ne "rabaisse" les éléments suivants?

nous constatons donc qu'il existe une différence dans le rendu des marges en fonction du côté auquel elles sont appliquées - les marges du haut (et de gauche) sont différentes de celles du bas (et de droite).

les choses deviennent de plus en plus claires lorsque l'on regarde (de manière simplifiée) la manière dont les styles sont appliqués par le navigateur: les éléments sont affichés de haut en bas dans la fenêtre d'affichage, en commençant par le coin supérieur gauche l'horizontal est traité de la même manière).

considérez le code HTML suivant:

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

analogues à leur position dans le code, ces trois cases apparaissent empilées 'du haut vers le bas' dans le navigateur ( en gardant les choses simples, nous ne considérerons pas ici la propriété order du css3 module 'flex-box' ). ainsi, chaque fois que des styles sont appliqués à la case 3, les positions des éléments précédents (pour les cases 1 et 2) ont déjà été déterminées et ne doivent plus être modifiées pour des raisons de rapidité de rendu.

maintenant, imaginez une marge supérieure de -10px pour la case 3. Au lieu de déplacer tous les éléments précédents pour gagner de l'espace, le navigateur va simplement pousser la case 3 vers le haut, de sorte qu'elle soit rendue au-dessus de (ou dessous, en fonction de l'index z). ) les éléments précédents. Même si les performances n'étaient pas un problème, déplacer tous les éléments vers le haut pouvait signifier de les déplacer hors de la fenêtre d'affichage. Par conséquent, la position de défilement actuelle devrait être modifiée pour que tout soit à nouveau visible.

il en va de même pour la marge inférieure de l'encadré 3, à la fois négative et positive: au lieu d'influencer les éléments déjà évalués, seul un nouveau "point de départ" pour les éléments à venir est déterminé. ainsi, en définissant une marge inférieure positive, appuyez sur les éléments suivants; un négatif les poussera.

15
schellmax

Étant donné que vous avez utilisé le positionnement absolu et que vous avez spécifié un pourcentage supérieur, seule la marge supérieure affectera l'emplacement de votre objet .item. Si au lieu de cela vous le positionniez en utilisant bottom: 50%, vous auriez besoin de -pax-margin-bottom pour le centrer, et margin-top n'aurait aucun effet.

La marge affecte les limites d'un élément en termes de positionnement, soit absolument comme dans votre cas, soit par rapport aux éléments voisins. Imaginez que cette marge soit le fondement de votre élément sur lequel elle repose. Ils ont généralement la même taille, mais peuvent être agrandis ou réduits sur l’un ou l’ensemble des quatre bords.

Votre code CSS indique au navigateur de placer la marge en haut de votre élément à un point situé à 50% du bas de la page. Toutefois, comme tous les éléments ne constituent pas un seul pixel, le navigateur doit savoir quelle partie de celui-ci doit être alignée à 50% de la page. Pour aligner le haut de l'élément, il utilise la marge supérieure. Par défaut, cela correspond au haut de l'élément, mais vous pouvez le modifier avec CSS.

Dans votre cas, le top 50% ferait en sorte que le haut de l'élément commence au milieu de la page. En appliquant une marge supérieure négative, le navigateur utilise le point 8px dans l’élément du haut (c’est-à-dire la ligne située au milieu de celui-ci) en tant qu’endroit à positionner à 50%.

Si vous appliquez une marge positive au bas, cela étend la ligne utilisée par le navigateur pour positionner le fond loin de l'élément lui-même, en laissant un espace entre celui-ci et tout élément adjacent situé en dessous, ou affectant l'emplacement où il est placé de manière absolue si le positionnement est basé sur le fond.

3
Rob Trickey

Je me demande si on a bien répondu à cette question: comment fonctionnent les marges css et pourquoi est-ce que margin-top: -5; n'est pas la même chose que margin-bottom: 5 ;?

La marge est la distance des environs de l'élément. margin-top indique "... la distance par rapport aux environs lorsque nous mesurons depuis le" côté "supérieur de la" boîte "de l'élément et la marge-inférieure correspond à la distance depuis le" côté "inférieur de la" boîte "". Puis marge supérieure: 5; concerne le périmètre "côté" supérieur, -5 dans ce cas; tout ce qui approche du haut du "côté" peut chevaucher le haut du "côté" de l'élément de 5, et le bord inférieur: 5; signifie que la distance entre le bas de l'élément et son environnement est égale à 5.

Fondamentalement cela, mais affecté par des éléments flottants et similaires: http://www.w3.org/TR/CSS2/box.html#margin-properties .

http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

Je tiens à être corrigé.

3
Maybe