Okay, ein paar Abstände kommen in eine Bar, stolpern und fallen zu Boden. Der Barkeeper fragt, ob er abserviert werden soll, und der Abstand antwortet: „Nein, ich bin nur ein zusammenfallender Rand.“
Entschuldigung, schlechter Witz.
Im Ernst, kollabierende Abstände sind real und können eine echte Plage sein, wenn Sie nicht wissen, was sie sind und wie sie sich verhalten. Hier sind ein paar Szenarien, in denen diese kleinen Dinger ins Spiel kommen.
Wenn vertikale Welten kollidieren
Kollabierende Abstände treten auf, wenn zwei vertikale Abstände miteinander in Kontakt kommen. Wenn ein Abstand größer ist als der andere, überschreibt dieser Abstand den anderen und hinterlässt einen Abstand.
Nehmen wir an, wir hätten Elemente übereinander gestapelt, eines mit einem unteren Abstand und eines mit einem oberen Abstand
.module {
display: block;
width: 100%;
height: 150px;
}
.module__top {
margin-bottom: 25px;
background-color: #f38a6d;
}
.module__bottom {
margin-top: 50px;
background-color: #3bbfef;
}
Wenn die obigen Module im HTML-Markup nebeneinander platziert sind, erwarten wir dann nicht richtig, dass vertikal 75px (25px vom oberen Modul plus 50px vom unteren Modul) dazwischen liegen?
Nun, in dieser Ausgabe von CSS Survival of the Fittest erhalten wir nur 50 dieser Pixel. Es ist, als ob der größere Abstand den anderen einfach verschlungen und nichts hinterlassen hätte.
Siehe den Pen Collapsing Margins: Vertical von CSS-Tricks (@css-tricks) auf CodePen.
Messen Sie ruhig nach. Der Abstand zwischen diesen beiden Modulen entspricht den 50px des module__bottom und wirft den Abstand von module__top über Bord.
Eine natürliche Reaktion könnte darin bestehen, den kleineren Abstand immer weiter zu erhöhen, bis er eine Wirkung zeigt. Aber ach, wenn beide Abstände positive Zahlen sind
größerer Abstand = gesamter vertikaler Abstand
Diejenigen unter Ihnen, die mathematisch versierter sind als ich, werden vielleicht clever fragen: Was ist mit negativen Abständen? Die Antwort ist, dass dies einen erheblichen Einfluss hat und den Abstand zwischen den beiden Elementen verringert.
50px + (-25px) = 25px
Auf Deutsch gesagt: Wenn ein Abstand negativ ist, wird der negative Abstand vom positiven Abstand abgezogen, wodurch der gesamte vertikale Abstand reduziert wird. So sieht das aus
Siehe den Pen Collapsing Margins: Vertical and Negative von CSS-Tricks (@css-tricks) auf CodePen.
Und wenn beide Abstände negativ sind? Die gleiche Regel gilt, als ob beide positiv wären. Allerdings kollabiert der größere negative Abstand von beiden, anstatt derjenige, der dem positiven am nächsten ist. Wenn beispielsweise ein Abstand -25px und der andere -50px beträgt, dann ist -50px der Abstand.
Eine weitere Situation, über die Sie sich vielleicht wundern, ist, wenn ein vertikaler Abstand auf einen gleichen vertikalen Abstand trifft. Wenn dies wirklich „Überleben der Stärksten“ wäre, dann sollten zwei kollidierende gleiche Abstände entweder zusammenleben oder zusammen sterben, richtig? Das ist ein guter Gedanke, aber was passiert ist, dass einer weiterhin verwendet wird und einer kollabiert. Es ist so, als ob einer den anderen verschluckt hätte, obwohl wir nicht sicher sind, welcher verschluckt wird.
Wenn Eltern ihre Kinder erden
Kollabierende Abstände treten auch auf, wenn der Abstand eines Kindelements den Abstand seines Elternteils überschreitet. Betrachten wir Folgendes
/* Parent */
div {
margin: 15px;
}
/* Here come the children */
.red {
background-color: #ff6b6b;
}
.orange {
background-color: #ff9e2c;
}
.yellow {
background-color: #eeee78;
}
.green {
background-color: #4ecd9d;
}
.blue {
background-color: #4e97cd;
}
.purple {
background-color: #6c4ecd;
}
In diesem Beispiel ist div der Elternteil und jede nachfolgende Klasse ist ein verschachteltes Kindelement. Das etabliert die Eltern-Kind-Beziehung.
Auch hier könnte unsere natürliche Neigung darin bestehen, dass der Gesamtabstand die Summe der Eltern- und Kindabstände ist. Das ist jedoch nicht der Fall, und der Kindabstand wird vom Elternabstand überschrieben – zumindest solange das Kindelement unter dem Dach des Elternteils lebt. Eltern können so bestimmend sein.
Aber wie bei jeder elterlichen Bestrafung gibt es einen Weg, dies zu umgehen, indem man etwas Solides zum Elternteil hinzufügt. In diesem Fall ermöglicht das Hinzufügen von 1px Padding die Nutzung beider Abstände.
Siehe den Pen Collapsing Margins: Parents and Children Comparison von CSS-Tricks (@css-tricks) auf CodePen.
Das Gleiche würde gelten, wenn wir dem Elternteil border-top hinzufügen würden. Solange etwas Solides zwischen Elternteil und Kind liegt, werden beide Abstände genutzt.
Fazit
Sehen Sie, wie kollabierende Abstände Dinge knifflig machen können? Ich persönlich stoße bei der Typografie immer wieder frustrierend darauf. Ich bin versucht, Dingen wie <h1> und <h2> Abstände hinzuzufügen, aber das ist oft die Quelle vieler Kopfschmerzen, da vertikale Abstände miteinander kollidieren.
Ich bin daran interessiert zu erfahren, was Sie alle über kollabierende Abstände denken. Insbesondere, wie verwalten Sie sie in einem musterbasierten System? Harry Roberts bietet einige gute Tipps. Bitte teilen Sie!
Deshalb wende ich im Allgemeinen nur margin-top auf Elemente an.
Gleich hier. Top-Abstände, besonders in der Typografie, waren eine gute Praxis und wurden zum De-facto-Standard für kodmunki! Es ist ein ausgezeichnetes „Muster“, das unzählige Entwicklungsstunden gespart und vielen Designern das plattgedrückte Gesicht, die schwarz gekloppten Augen und das in die Tastatur geschlagene Gesicht erspart hat! :{)}
Guter Artikel, nützliche, klare Informationen. Wurde schon mehr als einmal von kollabierenden Abständen frustriert :-)
Die Verwendung eines Clearfix zwischen den kollidierenden Elementen löst dies ebenfalls.
Ich halte mich an Harry Roberts Technik, nur margin-bottom zu verwenden. Es braucht etwas Gewöhnung, aber es lohnt sich sehr.
Als Bonus ist der typografische Rhythmus meiner Projekte merklich konsistenter und viel einfacher zu verwalten.
Ich folge Harrys Regel, seit er seinen Artikel veröffentlicht hat, und habe bisher jede Mühe mit kollabierenden Abständen vermieden. Wenn ich jedoch in Projekten mit kollabierenden Abständen konfrontiert wurde (bereits geschriebener Code), war dies eine gute Erinnerung daran, warum ich bidirektionale Abstände vermeide.
Etwas, das ich mich immer gefragt habe, ist, *warum* Abstände kollabieren – gibt es Umstände, in denen es nützlich ist?
Das Kollabieren von Abständen stammt aus dem Grafikdesign.
Dort haben Sie Abstände zu Titeln und Untertiteln, aber wenn ein Untertitel direkt nach dem Titel kommt, sollten Sie die Abstände nicht verdoppeln. Deshalb haben sie das Konzept der kollabierenden Abstände entwickelt und deshalb passiert es nur bei vertikalen Abständen.
Als Abstände in das Webdesign eingeführt wurden, waren Websites nur weiße Seiten mit formatiertem Text. Daher wurden Abstände hauptsächlich für Text oder Bilder innerhalb des Textes verwendet. Im Grunde waren alle Elemente display:inline, sodass die kollabierenden Abstände der Weg waren und zur Norm wurden.
Weil sie typografisch (zum Beispiel) **viel** mehr Sinn ergeben. Gibt es Umstände, in denen es *nicht* nützlich ist? ;)
Ich denke, es lohnt sich zu erwähnen, dass overflow hidden auch das Kollabieren von Abständen verhindert –> http://codepen.io/anon/pen/wazRXY
Wenn ich mich richtig erinnere, ist das der Grund, warum Micro Clearfix auch ein Before-Pseudo-Element hat. Andernfalls würden overflow hidden und Clearfix zu unterschiedlichen Ergebnissen führen.
Ich bemühe mich immer, die CSS-Eigenschaft margin-top zu vermeiden. Verwende nur margin-left, right und bottom für volle 100% Breite. Aber wenn es Tags auf derselben horizontalen Linie gibt, verwende ich tag+tag und schreibe nur links oder rechts Abstände.
Für leere Eltern und Kinder ohne Inhalt verwende ich immer Eigenschaften wie display block mit spezifischer Höhe und Breite.
Wenn wir damit konsequent sind, sollten wir jeden Raum wie erwartet erhalten.
Noch etwas. Wenn ich Pseudo-Elemente wie ::before und ::after verwende, um Dekorationen wie leeren Raum mit Farbe zu erzeugen, füge ich eine weitere Eigenschaft hinzu, die dazu dient, den Pseudo-Elementen „einen leeren Raum“ zu geben, wie content:“ “;
Wie andere schon sagten, verwende ich nur
margin-bottomund mache Ausnahmen nur, wenn es absolut notwendig ist. Falls nötig, kann diese Situation mit einigen Stilen speziell für Geschwisterelemente behandelt werden. Glücklicherweise haben wir den Geschwisterselektor+, um dies zu tun.Toller Beitrag! Hat alle meine Zweifel am Kollabieren von Abständen geklärt, besonders in Fällen, in denen wir einen positiven und einen negativen Abstand haben.
Hier sind sauberere Wege, um kollabierende Abstände zu vermeiden (keine 1px Padding- oder Border-Tricks)
http://codepen.io/Merri/pen/rVMRpq
Ja, display:inline-block ist eine gute Alternative.
Für Situationen, in denen Sie keine Breite von 100% verwenden können (altes IE und Padding/Border/Margin rechts/links), können Sie diesen Trick verwenden
http://codepen.io/anon/pen/RPoLRJ
Verwendet vor und nach Pseudo-Elementen mit Höhe und negativen Abständen, um das Padding des Elternelements zu erzwingen, ohne die Größe des ursprünglichen Inhalts zu beeinträchtigen.
Hat natürlich eigene Nachteile, da Sie vor- und nachgestellte Pseudo-Elemente verwenden müssen, die möglicherweise bereits für andere Zwecke benötigt werden.
Funktionierende Codepens (die andere wurde anonym erstellt)
{ float: left; width: 100% }wendet auch beide Abstände an, obwohl dieser Ansatz wegen des Floats nicht sehr elegant ist...Ich benutze seit Jahren nur margin-bottom und es funktioniert großartig. Ich versuche, meine Websites so modular wie möglich zu gestalten, daher muss ich mir bei der Verwendung von nur margin-bottom keine Sorgen machen, wie verschiedene Modulkombinationen zusammenpassen. Wenn ich einzigartige Abstandsbedürfnisse habe, verwende ich eher „Adjacent Sibling“ (
.this + .that) oder:last-childSelektoren, um diese spezifischen Fälle zu beheben.Ich verwende margin-top auf Elementen, die anderen Elementen vorausgehen: http://alistapart.com/article/axiomatic-css-and-lobotomized-owls.
Ähm... absolut nicht. Mathematik gibt uns eine sehr spezifische Bedeutung der Funktion
max(x,y). Wennx==y, dannmax(x,y)==x==y. Es ergibt keinen Sinn zu denken, dassmax(x,y)0 oderx+ywäre.Obwohl ich einige (leicht zu lösende) Probleme mit Containern und Ähnlichem sehe, wie würden Sie korrekt abgesetzte Absätze und Überschriften erstellen, *ohne* kollabierende Abstände?
Ich benutze normalerweise display: inline-block, float: left und clear: both…
Zwei germophobe Frauen stehen nebeneinander auf einem U-Bahn-Bahnsteig. Beide verlangen einen 12-Zoll-„Blase“ der Trennung von der anderen. Beide Frauen sind zufrieden, dass sie ihre wahrgenommene „Blase“ beibehalten haben, aber es gibt immer noch nur 12 Zoll (nicht 24) zwischen ihnen.
Ich habe mit diesem Konzept eigentlich keine Probleme, da ich Abstand immer als „gib mir *mindestens* so viel Freiraum von jedem *äußeren* Element“ betrachte. Wenn Sie jedoch möchten, dass diese Blase „meine, alles meine“ ist, dann verwenden Sie Padding. Padding ist eher wie „Ich möchte *nichts* berühren, weder äußere Elemente noch die Seite meines eigenen Containers.“ Abstände scheinen perfekt für das Kollabieren gemacht zu sein (oh, und für die schöne horizontale Zentrierung, a.k.a.
margin: x auto;).Wort! Seltsamerweise wäre in der CSS-Welt der Abstand zwischen diesen Frauen immer noch 24 Zoll, solange sie nebeneinander stehen (auf der horizontalen Achse). Er kollabierte nur auf 12 Zoll, wenn eine Frau über der anderen schweben würde.
Danke für das Teilen dieses Beitrags, ich bin neu im Bereich Webdesign und -entwicklung. Ihr Artikel wird mir beim Design meiner nächsten Website helfen.
Ich versuche, ein universelles Stylesheet zusammenzustellen.
Ich denke, ich mag die Idee, dass fast alle Elemente einen **Top-Abstand von 0px** haben und Bottom-Abstände zur Steuerung des vertikalen Abstands verwendet werden. Ich bin sicherlich auf viele Fälle gestoßen, in denen das Setzen von Top-Abständen bei Dingen Kopfschmerzen bereitet.
Problem 1: Ich möchte, dass P im Allgemeinen 1,5em unteren Abstand hat, aber wenn ein P über einem anderen P steht, möchte ich, dass sein unterer Abstand etwas geringer ist, z. B. 1em. Anders ausgedrückt, ein Haufen von Ps zusammen hätte weniger Abstand zwischen jedem als über und unter dem gesamten Haufen von Ps. Das wäre einfach, wenn wir einen Selektor hätten, der auf den vorderen Geschwister von etwas wie diesem wirkt:
p+p. Aber wir wissen, dass dies nur das letzte P in der Anweisung auswählt.Problem 2: Ebenso möchte ich P (und mehrere andere Blockelemente wie UL, Tabelle usw.) einen unteren Abstand von 1,5em haben, *es sei denn*, sie werden von einem H1-6-Tag gefolgt, in welchem Fall ich 1,8em möchte. Wieder wäre ein Selektor, der auf das erste Element in der Anweisung wirkt (z. B. p+H1), das, was ich brauche.
Also…
Weiß jemand, wie man ein P auswählt, nur wenn es von einem H1 gefolgt wird?
Oder ein P, dem ein anderes P folgt?
Ideen
Wenn es einfach keinen Selektor gibt, der die Aufgabe natürlich erledigt…
Was beide Probleme lösen könnte, ist die Erstellung einer Klasse (vielleicht benannt „needExtraSpacingBecauseImTheLastOne“), um mehr Abstand zu geben an jedes Element, das einem H1 oder einem anderen Header-Tag vorausgeht.
Für Problem 2 könnte ich einen Top-Abstand auf die Header setzen, aber eine Klasse erstellen, die ich auf jeden von ihnen setzen könnte, um den Top-Abstand auf Null zu setzen (wie wenn es die erste Überschrift in einem Block/einer Seite wäre und ich den zusätzlichen Top-Abstand nicht wollte).
Oder einfach
p+h1verwenden und den oberen Abstand erhöhen, da Sie Absätze gefolgt von Überschriften (oder Überschriften gefolgt von Absätzen, es ist dasselbe) ansprechen möchten. Viel einfacher und vermeidet unnötige Klassen.Danke für die Antwort, Lazza.
P ist jedoch nicht der einzige Tag, den ich in diese Art von Geschwisternotation aufnehmen müsste. Ich müsste blockquote+h1, form+h1, ul+h1 und einige andere hinzufügen. Wenn Sie also die vielleicht 9 Block-Level-Tags nehmen und alle 6 H-Tags durchlaufen, erhalten Sie 54 Anweisungen, die Sie haben müssen, im Gegensatz zu sechs H.noMarginAbove-ähnlichen Klassen. Das macht die Klassen überlegenswert.
Ihre Idee könnte jedoch für meine Situation richtig sein. Ich werde sie mir auf jeden Fall ansehen. Danke!