Margin-Top äußere Div nach unten drücken

126

Ich habe ein Header-Div als erstes Element in meinem Wrapper-Div, aber wenn ich einem h1 innerhalb des Header-Div einen oberen Rand hinzufüge, wird das gesamte Header-Div nach unten gedrückt. Mir ist klar, dass dies immer dann passiert, wenn ich einen oberen Rand auf das erste sichtbare Element auf einer Seite anwende.

Hier ist ein Beispielcode-Snippet. Vielen Dank!

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>

Danny
quelle

Antworten:

192

Setzen Sie overflow:autoin die Eltern div
sehen Sie mehr in diesem Link

Juan Pablo
quelle
29
overflow:hiddenist in 90% der Fälle besser.
vsync
1
Warum sollte Überlauf: versteckt besser sein?
Peterchon
5
@ Peterchon - weil Auto Bildlaufleisten verursachen kann
vsync
3
funktioniert nicht mehr, die Antwort von @ SW4 in diesem Link ist besser
am05mhz
1
overflow: hiddenoder overflow: autokann unerwünschte Nebenwirkungen verursachen, von denen einige möglicherweise nicht auf den ersten Blick sichtbar sind. Ich habe festgestellt, dass das Wechseln marginzu paddingden Trick macht, wie die Antwort unten nahelegt. Ich verstehe immer noch nicht, warum das ganze Problem passiert.
Gilad Barner
34

Ich habe nicht eine solide Erklärung, warum dies geschieht, aber ich habe dieses Problem behoben , indem die top-marginzu top-paddingoder dem Hinzufügen von display: inline-blockdem Elemente Stil.

EDIT: Das ist meine Theorie

Ich habe das Gefühl, dass es etwas damit zu tun hat, wie Ränder reduziert (kombiniert) werden.

von W3C Collapsing Margins :

In dieser Spezifikation bedeutet der Ausdruck "Ränder reduzieren", dass benachbarte Ränder (kein nicht leerer Inhalt, Polsterung oder Randbereiche oder Abstand trennen sie) von zwei oder mehr Feldern (die nebeneinander oder verschachtelt sein können) zusammen einen einzigen Rand bilden .

Meine Theorie ist, dass, da sich Ihr erstes Element neben dem Körper befindet, die beiden Ränder kombiniert und auf den Körper angewendet werden: Dies zwingt den Körperinhalt dazu, gemäß dem Box-Modell unter dem angewendeten reduzierten Rand zu beginnen .

Es gibt Situationen, in denen die Ränder nicht kollabieren, was es wert sein könnte, damit herumzuspielen (von 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
digitaler Träumer
quelle
3
Durch Auffüllen oder Umrandung des Elements mit reduziertem Rand (dem inneren Rand) wird es nicht mehr reduziert.
Anonym
Das hat bei mir funktioniert - ich hatte absolute Elemente (ein Dropdown) in meinem Container, also Überlauf: Auto hat nicht funktioniert.
Mwilcox
17

Dies sind einige der Möglichkeiten, um zu vermeiden, dass der Rand zwischen Eltern-Kind-Elementen zusammenbricht. Verwenden Sie diejenige, die besser zum Rest Ihres Stylings passt:

  • Auf displayandere als einstellen block.
  • Auf floatandere als einstellen none.
  • Entfernen Sie den Rand und verwenden Sie stattdessen padding. Wenn Sie zum Beispiel hatten margin-top: 10px, ersetzen Sie durch padding-top: 10px;.
  • Entfernen Sie den Rand, und verwenden Sie stattdessen position( absoluteoder relative) mit Attributen top, bottometc. Zum Beispiel , wenn Sie hatte margin-top: 10px, ersetzen position: relative; top: 10px;.
  • Fügen Sie dem übergeordneten Element ein paddingoder ein borderan der Seite hinzu, an der die Ränder reduziert werden . Der Rand kann 1px und transparent sein.
  • Auf overfloweinen anderen Wert als visibledas übergeordnete Element setzen.
Jesús Carrera
quelle
5

Ich weiß, dass dies ein altes Problem ist, ich bin oft darauf gestoßen. Das Problem ist, dass alle Korrekturen hier Hacks sind, die möglicherweise unbeabsichtigte Konsequenzen haben würden.

Zunächst gibt es eine einfache Erklärung für das Grundproblem. Aufgrund der Art und Weise, wie das Reduzieren von Rändern funktioniert, wird dieser obere Rand effektiv auf den übergeordneten Container selbst angewendet, wenn das erste Element in einem Container einen oberen Rand hat. Sie können dies selbst testen, indem Sie Folgendes tun:

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

Öffnen Sie dies in einem Debugger und bewegen Sie den Mauszeiger über das Div. Sie werden feststellen, dass das div selbst tatsächlich dort platziert ist, wo der obere Rand des H1-Elements stoppt . Dieses Verhalten wird vom Browser beabsichtigt.

Es gibt also eine einfache Lösung, ohne auf seltsame Hacks zurückgreifen zu müssen, wie es die meisten Posts hier tun (keine Beleidigungen beabsichtigt, es ist nur die Wahrheit) - kehren Sie einfach zur ursprünglichen Erklärung zurück - ...if the first element inside a container has a top margin...- Danach würden Sie daher brauchen Das erste Element in einem Container, das KEINEN oberen Rand hat. Okay, aber wie machen Sie das, ohne Elemente hinzuzufügen, die Ihr Dokument nicht semantisch stören?

Einfach! Pseudoelemente! Sie können dies über eine Klasse oder ein vordefiniertes Mixin tun. Fügen Sie ein :beforePseudoelement hinzu:

CSS über eine Klasse:

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

Wenn Sie dem obigen Markup-Beispiel folgen, würden Sie Ihr div als solches ändern:

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

Warum funktioniert das?

Das erste Element in einem Container legt, wenn es keinen oberen Rand hat, die Position des Beginns des oberen Randes des nächsten Elements fest. Durch Hinzufügen eines :beforePseudoelements fügt der Browser dem übergeordneten Container vor Ihrem ersten Element tatsächlich ein nicht-semantisches (mit anderen Worten gut für SEO) Element hinzu.

Q. Warum die Höhe: .0000001em?

A. Der Browser benötigt eine Höhe, um das Randelement nach unten zu drücken. Diese Höhe ist praktisch Null, aber Sie können trotzdem dem übergeordneten Container selbst Polster hinzufügen. Da es praktisch Null ist, hat es auch keine Auswirkungen auf das Layout des Containers. Wunderschönen.

Jetzt können Sie eine Klasse (oder besser in SASS / LESS ein Mixin!) Hinzufügen, um dieses Problem zu beheben, anstatt seltsame Anzeigestile hinzuzufügen, die unerwartete Konsequenzen haben, wenn Sie andere Dinge mit Ihren Elementen tun möchten, und die Ränder von Elementen gezielt eliminieren und / oder es durch Auffüllen oder seltsame Positions- / Float-Stile zu ersetzen, die dieses Problem wirklich nicht lösen sollen.

Dudewad
quelle
2
Die .0000001em wird in IE11 wirklich auf Null gerundet, wodurch Ihr Fix beschädigt wird. Wenn ich es auf .01em ändere, funktioniert es trotzdem.
Esger
1
Ich stelle mir vor, dass .01em ausreichen wird, um immer noch effektiv Null zu sein. Guter Punkt. Auf der anderen Seite, jetzt, da es 2018 ist, werden viele von uns die Unterstützung für IE11 bald einstellen, insbesondere mit der jüngsten Ankündigung, dass MS erneut einen neuen Browser bauen wird (außer diesmal auf Chrombasis, was theoretisch bedeutet) - wird nicht total saugen). : D
Dudewad
2

display: flexwird in diesem Fall funktionieren. Geben display: flex;Sie dem h1Tag ein übergeordnetes Element und dann einen Rand gemäß Ihren Anforderungen an .

Bijay
quelle
0

Laufen Sie heute auf dieses Problem.

overflow: hidden funktionierte nicht wie erwartet, als mir weitere Elemente folgten.

Also habe ich versucht, die Anzeigeeigenschaft des übergeordneten Divs zu ändern und habe display: flexgearbeitet !!!

Hoffe das kann jemandem helfen. :) :)

Libin
quelle
0

Durch Hinzufügen eines winzigen Auffüllens zum oberen Rand des übergeordneten Elements kann dieses Problem behoben werden.

.parent{
  padding-top: 0.01em;
}

Dies ist nützlich, wenn ein Element innerhalb des übergeordneten Elements außerhalb des übergeordneten Elements sichtbar sein soll, z. B. wenn Sie einen überlappenden Effekt erstellen.

adamspruijt
quelle
0

Dies geschieht aufgrund eines Randkollapses. Wenn das untergeordnete Element die Grenze des übergeordneten Elements berührt und eines davon mit Rändern angewendet wird, gilt Folgendes:

  1. Die größte Marge gewinnt (angewendet).

  2. Wenn einer von ihnen einen Spielraum hat, teilen sich beide den gleichen.

Lösungen

  1. Wenden Sie einen Rand auf den Elternteil an, wodurch Eltern und Kind getrennt werden.
  2. Wenden Sie Auffüllungen auf Eltern an, wodurch Eltern und Kind getrennt werden.
  3. Überlauf anwenden, anstatt auf dem übergeordneten Element sichtbar zu sein.
  4. Verwenden Sie vorher oder nachher, um ein virtuelles Element im übergeordneten div zu erstellen, das sich vom Rand des untergeordneten und des übergeordneten Elements unterscheiden kann.
  5. Erstellen Sie ein HTML-Element zwischen Rand angewendet Kind und Eltern kann sie auch trennen.
Ishu
quelle