Wie deaktiviere ich das Reduzieren von Rändern?

202

Gibt es eine Möglichkeit, das Zusammenfallen von Rändern insgesamt zu deaktivieren? Die einzigen Lösungen, die ich gefunden habe (unter dem Namen "Uncollapsing"), sind die Verwendung eines 1-Pixel-Rahmens oder einer 1-Pixel-Polsterung. Ich finde das inakzeptabel: Das fremde Pixel erschwert die Berechnungen ohne guten Grund. Gibt es eine vernünftigere Möglichkeit, diesen Margin-Collapse zu deaktivieren?

kjo
quelle
4
Verwenden Sie das Flex- oder Grid-Layout, bei dem das Reduzieren von Rändern
Michael Benjamin
Geben Sie den Elementen einfach einen Wert für, margin-bottomaber lassen Sie ihn margin-topals 0.
Dan Bray
Ich habe ein Paket erstellt, um die Berechnung zu vereinfachen: npmjs.com/package/collapsed-margin
Owen M

Antworten:

254

Es gibt zwei Haupttypen des Randkollapses:

  • Reduzierende Ränder zwischen benachbarten Elementen
  • Reduzieren von Rändern zwischen übergeordneten und untergeordneten Elementen

Die Verwendung einer Polsterung oder eines Randes verhindert nur im letzteren Fall ein Zusammenfallen. Außerdem verhindert jeder Wert, der overflowvon seinem visibleauf das übergeordnete Element angewendeten Wert ( ) abweicht, das Zusammenfallen. Somit haben beide overflow: autound overflow: hiddenden gleichen Effekt. Möglicherweise ist der einzige Unterschied bei der Verwendung hiddendie unbeabsichtigte Folge des Ausblendens von Inhalten, wenn der Elternteil eine feste Höhe hat.

Andere Eigenschaften, die nach dem Anwenden auf das übergeordnete Element zur Behebung dieses Verhaltens beitragen können, sind:

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

Sie können alle hier testen: http://jsfiddle.net/XB9wX/1/ .

Ich sollte hinzufügen, dass Internet Explorer wie üblich die Ausnahme ist. Insbesondere werden in IE 7 Ränder nicht reduziert, wenn für das übergeordnete Element ein Layout angegeben wird, z width.

Quellen: Sitepoints Artikel Collapsing Margins

hqcasanova
quelle
1
Beachten Sie, dass Polsterung dies auch beeinflussen kann, wenn es nicht Null ist
Mladen Janjetovic
3
Beachten Sie, dass dies overflow: autodazu führen kann, dass Bildlaufleisten im übergeordneten Element angezeigt werden, anstatt dass der Inhalt überläuft overflow: visible.
Leo
'overflow: auto' scheint in Chrome v44 nicht zu funktionieren.
tkane2000
3
Danke für die Anzeige: Inline-Block, es hat mich gerettet :)
Alexcasalboni
3
Jeder flexandere Wert als der Standardwert deaktiviert auch den Randkollaps
Oly,
60

Sie können hierfür auch den guten alten Micro Clearfix verwenden.

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

Siehe aktualisierte Geige: http://jsfiddle.net/XB9wX/97/

Blackgrid
quelle
Habe meine Antwort in ein Community-Wiki verwandelt. Bitte zögern Sie nicht, es mit Ihrer Antwort zu erweitern. Vielen Dank.
Hqcasanova
3
Ich verstehe es nicht, wenn ich mir dieses Beispiel ansehe, kollabieren die Ränder (nur 10px vertikaler Abstand zwischen den Divs statt 20px)
Andy
1
Dies hilft nur beim Entfernen des Zusammenbruchs zwischen Geschwistern, auf die alle diesen Clearfix angewendet haben. Ich habe das Beispiel gegabelt, um dies zu demonstrieren: jsfiddle.net/dpyuyg07 --- und selbst das ist nicht die ganze Geschichte. Es wird nur das Zusammenfallen von Rändern entfernt, die von untergeordneten Elementen der Elemente stammen, auf die Sie diesen Fix angewendet haben. Wenn Sie dem Container selbst einen Rand hinzufügen würden, würden die Ränder immer noch zusammenbrechen, was in dieser Gabelung zu sehen ist: jsfiddle.net/oew7qsjx
NicBright
4
Ich kann das noch genauer sagen: Die Clearfix-Methode verhindert nur den Randkollaps zwischen Eltern und Kindern. Der Zusammenbruch zwischen benachbarten Geschwistern ist davon nicht betroffen.
NicBright
Ich glaube, ich verstehe jetzt die Tendenz von Bootstrap, das DOM mit :beforeund :afterElementen zu füllen . Ich habe diese Regel jetzt zu meinem Stylesheet hinzugefügt : div:before, div:after{content: ' '; display: table;}. Fantastisch. Plötzlich verhält sich das Zeug wie erwartet.
Stijn de Witt
59

Ein guter Trick, um das Zusammenfallen von Rändern zu deaktivieren, der meines Wissens keine visuellen Auswirkungen hat, besteht darin, die Polsterung des übergeordneten Elements auf Folgendes einzustellen 0.05px:

.parentClass {
    padding: 0.05px;
}

Die Polsterung ist nicht mehr 0, so dass kein Kollabieren mehr auftritt, aber gleichzeitig ist die Polsterung klein genug, um sie visuell auf 0 abzurunden.

Wenn eine andere Polsterung gewünscht wird, wenden Sie die Polsterung beispielsweise nur auf die "Richtung" an, in der das Zusammenfallen des Randes nicht erwünscht ist padding-top: 0.05px;.

Arbeitsbeispiel:

.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>

Bearbeiten: hat den Wert von 0.1auf geändert 0.05. Wie Chris Morgan in einem Kommentar unten erwähnte, und aus diesem kleinen Test geht hervor , dass Firefox tatsächlich die 0.1pxPolsterung berücksichtigt. Obwohl, 0.05pxseemes den Trick zu tun.

Nicu Surdu
quelle
2
Dies ist meine Lieblingslösung. Sie können dies sogar als Standardstil einfügen. Warum nicht? *{padding-top:0.1px}. Sind wir sicher, dass es in allen Browsern funktioniert?
Nick Manning
Hat bisher ziemlich gut für mich funktioniert, aber ich behaupte nicht, es in den meisten Browsern gründlich getestet zu haben.
Nicu Surdu
2
Sehr schöne Lösung, es scheint auf den meisten Browsern wie erwartet zu funktionieren. Danke, dass du es geteilt hast!
Wiredolphin
1
Dies ist eine zweifelhafte Lösung , da es nicht zusätzliche Pixel in verschiedenen Umständen hinzuzufügen, aufgrund hoher DPI - Displays und Subpixel - Berechnungen. (Firefox hat seit Ewigkeiten Subpixel-Layout erstellt, ich glaube, andere Browser sind vergleichsweise kürzlich gefolgt.)
Chris Morgan
0.05pxscheint immer noch eine bestimmte Wahl zu sein, keine zufällige Browser-Trickzahl, ich würde es vorziehen 0.01px.
Volker E.
22

overflow:hidden verhindert kollabierende Ränder, ist aber nicht frei von Nebenwirkungen - nämlich ... verbirgt Überlauf.

Abgesehen von diesem und dem, was Sie erwähnt haben, müssen Sie nur lernen, damit zu leben und für diesen Tag zu lernen, an dem sie tatsächlich nützlich sind (kommt alle 3 bis 5 Jahre).

Litek
quelle
Habe meine Antwort in ein Community-Wiki verwandelt. Ich glaube, ich habe den Nebeneffekt behandelt, den Sie in den letzten beiden Zeilen des zweiten Absatzes erwähnt haben: Vielleicht ist der einzige Unterschied bei der Verwendung von versteckt die unbeabsichtigte Folge des Versteckens von Inhalten, wenn der Elternteil eine feste Größe hat . Wenn Sie jedoch der Meinung sind, dass weitere Erläuterungen erforderlich sind, können Sie gerne einen Beitrag leisten. Vielen Dank.
Hqcasanova
7
overflow: autoist gut zu verwenden, um versteckte Überläufe und dennoch das Zusammenfallen von Rändern zu verhindern.
Gavin
@ Gavin, overflow:auto;mein Inhaltsbereich hat auf einigen Seiten eine Bildlaufleiste erhalten.
Reed
13

Eigentlich gibt es eine, die einwandfrei funktioniert:

Anzeige: flex; Flex-Richtung: Säule;

Solange Sie mit der Unterstützung von nur IE10 und höher leben können

.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>

Daniel Koster
quelle
Damit dies als generische Lösung funktioniert, muss ein zusätzliches <div>innerhalb des hinzugefügt werden .container, andernfalls .containerwird das Box-Modell seiner Kinder gesteuert. Inline-Elemente werden beispielsweise zu Blockelementen voller Breite. Wenn sie Ränder haben, werden diese ebenfalls reduziert.
zupa
9

Jeder Webkit-basierte Browser sollte die Eigenschaften unterstützen -webkit-margin-collapse . Es gibt auch Untereigenschaften, um sie nur für den oberen oder unteren Rand festzulegen. Sie können die Werte reduzieren (Standard), verwerfen (setzt den Rand auf 0, wenn ein benachbarter Rand vorhanden ist) und trennen (verhindert das Reduzieren des Randes).

Ich habe getestet, dass dies auf 2014-Versionen von Chrome und Safari funktioniert. Leider glaube ich nicht, dass dies im IE unterstützt wird, da es nicht auf Webkit basiert.

Eine vollständige Erklärung finden Sie in der Safari CSS-Referenz von Apple .

Wenn Sie die Seite mit den CSS-Webkit-Erweiterungen von Mozilla überprüfen , werden diese Eigenschaften als proprietär aufgeführt und empfohlen, sie nicht zu verwenden. Dies liegt daran, dass sie wahrscheinlich nicht in Kürze in Standard-CSS einsteigen werden und nur von Webkit-basierten Browsern unterstützt werden.

Dan Carter
quelle
Das ist schön, weil es uns hilft, eine Inkonsistenz im Umgang von Safari und Chrome mit Margen auszugleichen.
Judson
8

Ich weiß, dass dies ein sehr alter Beitrag ist, wollte aber nur sagen, dass die Verwendung von Flexbox für ein übergeordnetes Element das Reduzieren des Randes für seine untergeordneten Elemente deaktivieren würde.

Genzo
quelle
Nicht nur für die untergeordneten Elemente, sondern auch, dass der Rand zwischen dem übergeordneten Element und dem ersten und letzten untergeordneten Element nicht zusammenfällt.
Sven Marnach
2

Ich hatte ein ähnliches Problem mit dem Randkollaps, weil die Eltern positionauf relativ gesetzt hatten. Hier ist eine Liste von Befehlen, mit denen Sie das Reduzieren von Rändern deaktivieren können.

HIER IST SPIELPLATZ ZU TESTEN

Versuchen Sie einfach , alle zuweisen parent-fix*Klasse div.containerElement oder jede Klasse children-fix*zu div.margin. Wählen Sie diejenige aus, die Ihren Anforderungen am besten entspricht.

Wann

  • Das Reduzieren von Rändern ist deaktiviert . Der div.absoluterote Hintergrund wird ganz oben auf der Seite positioniert.
  • Der Rand kollabiert und div.absolute wird an derselben Y-Koordinate wie positioniertdiv.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>

Hier ist jsFiddle mit einem Beispiel, das Sie bearbeiten können

Buksy
quelle
1

In einem neueren Browser (außer IE11) wird eine einfache Lösung verwendet, um zu verhindern, dass Eltern-Kind-Ränder kollabieren display: flow-root. Sie benötigen jedoch noch andere Techniken, um das Zusammenfallen benachbarter Elemente zu verhindern.

DEMO (vorher)

.parent {
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

DEMO (nach)

.parent {
  display: flow-root;
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

Chuanqi Sonne
quelle
0

Zu Ihrer Information könnten Sie Gitter verwenden, aber mit Nebenwirkungen :)

.parent {
  display: grid
}
Whisher
quelle