web-dev-qa-db-fra.com

Margin-Top Poussez div externe

J'ai un div en-tête en tant que premier élément de mon div wrapper, mais lorsque j'ajoute une marge supérieure à un h1 à l'intérieur du div en-tête, il enfonce tout le div en-tête. Je me rends compte que cela se produit chaque fois que j'applique une marge supérieure au premier élément visible d'une page. 

Voici un exemple d'extrait de code. Merci!

div#header{
	width: 100%;
	background-color: #eee;
	position: relative;
}

div#header h1{
	text-align: center;
	width: 375px;
	height: 50px;
	margin: 50px auto;
	font-size: 220%;
	background: url('../../images/name_logo.png') no-repeat;
}
<div id="header">
	<h1>Title</h1>
	<ul id="navbar"></ul>
</div>

118
Danny

mettre overflow:auto dans le parent div
voir plus dans ce lien

176
JuanPablo

Je ne vois pas pourquoi cela se produit, mais j'ai résolu ce problème en remplaçant le top-margin par top-padding ou en ajoutant display: inline-block au style de l'élément.

EDIT: Ceci est ma théorie

J'ai l'impression que cela a quelque chose à voir avec la façon dont les marges sont réduites (combinées).

from W3C Collapsing Margins :

Dans cette spécification, l'expression la réduction des marges signifie que des marges adjacentes (pas de zones non vides de contenu, de marges intérieures ou de marges ou de séparation les séparent) de deux ou plusieurs cases (qui peuvent être adjacentes à une une ou imbriquées) se combinent pour former un marge unique.

Ma théorie est que, puisque votre premier élément est à côté du corps, les deux marges se combinent et sont appliquées au corps: cela force le contenu du corps à commencer en dessous de la marge effondrée appliquée conformément au modèle box .

Il existe des situations dans lesquelles les marges ne s'effondrent pas et dans lesquelles il pourrait être intéressant de jouer (de Collapsing Margins ):

* floated elements
* absolutely positioned elements
* inline-block elements
* elements with overflow set to anything other than visible (They do not collapse margins with their children.)
* cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
* the root element
31
digitaldreamer

Voici quelques-uns des moyens d'éviter la réduction des marges entre les éléments parent-enfant. Utilisez celui qui correspond le mieux à votre style:

  • Définissez display sur autre que block.
  • Définissez float sur autre que none.
  • Supprimez la marge et utilisez plutôt padding. Par exemple, si vous aviez margin-top: 10px, remplacez par padding-top: 10px;.
  • Supprimez la marge et utilisez plutôt position (absolute ou relative) avec les attributs top, bottom, etc. Par exemple, si vous avez eu margin-top: 10px, remplacez-le par position: relative; top: 10px;.
  • Ajoutez une padding ou une border du côté où les marges sont réduites, à l'élément parent. La bordure peut être 1px et transparente.
  • Définissez overflow sur autre que visible sur l'élément parent.
14
Jesús Carrera

Je sais que c'est un vieux problème, je l'ai rencontré à plusieurs reprises. Le problème est que toutes les solutions apportées ici sont des hacks qui pourraient potentiellement avoir des conséquences inattendues. 

Tout d'abord, il y a une explication simple au problème fondamental. En raison du fonctionnement de la réduction des marges, si le premier élément d'un conteneur a une marge supérieure, cette dernière est appliquée au conteneur parent lui-même. Vous pouvez le tester vous-même en procédant comme suit:

<div>
    <h1>Test</h1>
</div>

Dans un débogueur, ouvrez-le et survolez la div. Vous remarquerez que la div elle-même est réellement placée à l'endroit où la marge supérieure de l'élément H1 s'arrête . Ce comportement est prévu par le navigateur.

Donc, il y a une solution facile à cela sans avoir à recourir à des hacks étranges, comme le font la plupart des messages ici (pas d'insultes, c'est tout simplement la vérité) - retournez simplement à l'explication originale - ...if the first element inside a container has a top margin... - Ensuite, vous voudriez besoin du premier élément d'un conteneur pourPASavoir une marge supérieure. OK, mais comment fait-on cela sans ajouter des éléments qui n'interfèrent pas sémantiquement avec votre document?

Facile! Pseudo-éléments! Vous pouvez le faire via une classe ou un mixin prédéfini. Ajoutez un pseudo-élément :before:

CSS via une classe:

.top-margin-fix:before {   
    content: ' ';
    display: block;
    width: 100%;
    height: .0000001em;
}

Avec ceci, en suivant l'exemple de marquage ci-dessus, vous modifieriez votre div en tant que telle:

<div class="top-margin-fix">
    <h1>Test</h1>
</div>

Pourquoi ça marche?

Le premier élément d'un conteneur, s'il n'a pas de marge supérieure, définit la position du début de la marge supérieure de l'élément suivant. En ajoutant un pseudo-élément :before, le navigateur ajoute en fait un élément non sémantique (en d’autres termes, bon pour le référencement) dans le conteneur parent avant votre premier élément.

Q. Pourquoi la hauteur: .0000001em?

A. Une hauteur requise par le navigateur pour pousser l'élément de marge vers le bas. Cette hauteur est effectivement égale à zéro, mais elle vous permet tout de même d'ajouter du remplissage au conteneur parent lui-même. Étant donné que c'est effectivement zéro, cela n'aura aucun effet sur la disposition du conteneur. Belle.

Vous pouvez maintenant ajouter une classe (ou mieux, dans SASS/LESS, un mixin!) Pour résoudre ce problème plutôt que d'ajouter des styles d'affichage étranges qui entraîneront des conséquences inattendues lorsque vous souhaitez utiliser d'autres éléments, en éliminant délibérément les marges des éléments et/ou le remplacer par un rembourrage ou des styles de position/float étranges qui ne sont vraiment pas destinés à résoudre ce problème.

3
dudewad

display: flex fonctionnera dans ce cas. Donnez l'élément parent display: flex;, puis attribuez une marge à votre balise h1

2
Bijay

Courez dans cette affaire aujourd'hui.

overflow: hidden n'a pas fonctionné comme prévu lorsque d'autres éléments ont été suivis.

J'ai donc essayé de changer la propriété d'affichage de la div etdisplay: flextravaillé !!!

J'espère que cela peut aider quelqu'un. :)

0
Libin

Cela se produit à cause de l'effondrement de la marge . Lorsque l'élément enfant touche la limite de l'élément parent et que l'un d'entre eux est appliqué avec des marges, alors:

  1. La marge qui est la plus grande gagnera (appliquée).

  2. si l'un d'entre eux ayant une marge, les deux partagent la même chose.

Solutions

  1. applique une bordure au parent qui sépare le parent et l'enfant.
  2. applique un rembourrage au parent qui sépare le parent et l'enfant.
  3. appliquer un débordement plutôt que visible sur le parent.
  4. utiliser avant ou après pour créer un élément virtuel dans div parent qui peut différer de la marge appliquée enfant et parent.
  5. créer un élément html entre la marge appliquée enfant et parent peut aussi les séparer.
0
Ishu

L'ajout d'un petit peu de remplissage au sommet de l'élément parent peut résoudre ce problème.

.parent{
  padding-top: 0.01em;
}

Cela est utile si vous avez besoin qu'un élément du parent soit visible en dehors de celui-ci, comme si vous créiez un effet qui se chevauchait.

0
adamspruijt