CSS3-Box-Größe: Rand-Box; Warum nicht?

139

Warum haben wir nicht box-sizing: margin-box;? Wenn wir box-sizing: border-box;unsere Stylesheets einfügen, meinen wir normalerweise erstere.


Beispiel:

Angenommen, ich habe ein zweispaltiges Seitenlayout. Beide Säulen haben eine Breite von 50%, sehen aber irgendwie hässlich aus, weil es keine Rinne gibt (Lücke in der Mitte); Unten ist das CSS:

.col2 {
    width: 50%;
    float: left;
}


Um eine Dachrinne anzubringen, könnten Sie denken, wir könnten einfach einen rechten Rand für die erste der beiden Spalten festlegen. etwas wie das:

.col2:first-child {
    margin-right: 24px;
}

Dies würde jedoch dazu führen, dass die zweite Spalte in eine neue Zeile umgebrochen wird, da Folgendes zutrifft:

50% + 50% + 24px > 100%

box-sizing: margin-box;würde dieses Problem lösen, indem der Rand in die berechnete Breite des Elements aufgenommen wird. Ich würde dies sehr nützlich finden, wenn nicht nützlicher als box-sizing: border-box;.

Webdesigner
quelle
30
"Warum haben wir nicht box-sizing: margin-box;?" Denn während horizontale Ränder nicht kollabieren, würde ein solcher Vorschlag den Kollaps vertikaler Ränder ernsthaft beeinträchtigen. Wenn Sie etwas für die Standardisierung vorschlagen möchten, ist der Stapelüberlauf nicht der richtige Ort. Probieren Sie die Mailinglisten aus.
BoltClock
16
In bestimmten Situationen können Sie dies umgehen border: xxx solid transparent;, indem Sie den Rahmen in verwenden border-box. Dies wird jedoch einige andere Dinge zerstören, wie z box-shadow.
Nathan Osman
28
Schließen wir jetzt alle Fragen zu Standards als "nicht konstruktiv"? Es ist eine faire Frage, die gestellt werden muss, und sie hat sogar eine einfache Antwort: Wir haben sie nicht, box-sizing: margin-boxweil sie nicht mit einem Zusammenbruch der Margen funktionieren würde.
Thomasrutter
@thomasrutter: Als ich es vor mehr als einem Jahr schloss, gab es keinen besseren Grund dafür. Wie auch immer, "nicht konstruktiv" ist jetzt weg (was bedeutet, nein, wir schließen eigentlich nichts mehr als nicht konstruktiv), und da das Ganze "Ich habe eine Idee, hier ist, wie es funktioniert, machen wir dies zu einem Standard!" Das Ding wurde entfernt, seit es das letzte Mal geschlossen wurde. Es klingt jetzt tatsächlich wie ein praktisches "Warum kann X nicht funktionieren?" Frage. Es ist immer noch eine unglaublich spekulative Frage (meine obigen Überlegungen sind eigentlich nichts weiter als eine fundierte Vermutung), aber ich werde das nicht weiter kommentieren.
BoltClock
Warum nicht einfach einen inneren Wrap / Div haben, wenn Sie Abstand wollen: codepen.io/chriscoyier/pen/eGcLw
ashley

Antworten:

55

Könnten Sie nicht width: calc(50% - 24px);für Ihre Cols verwenden? Stellen Sie dann Ihre Ränder ein.

Slouch
quelle
5
Es ist stark browserabhängig. Wahrscheinlich um 2020 wird das ie15 es unterstützen und Sie dürfen das auch in Ihrer Arbeit verwenden :-(
peterh - Reinstate Monica
1
Scheint in Firefox nicht so gut zu funktionieren? (oder etwas anderes, was ich getan habe, ist nicht)
Laurengineer
@ Morgan Feeney: Ja, aber Box-Sizing hat keinen Wert namens Margin-Box (das ist der springende Punkt dieser Frage). Selbst wenn ein solcher Wert jetzt eingeführt wurde, wie schlagen Sie vor, ihn in vorhandene Browser zu patchen / zu füllen / zu shimmen?
BoltClock
Ja, aber ... speziell auf eine Antwort antworten, die calc () als Problemumgehung vorschlägt.
Morgan Feeney
Ich bin mir nicht sicher, ob dies für das spezifische Beispiel gilt, aber ein wesentlicher Nachteil bei der Verwendung von calc () in unserem Szenario (wie bei FF 53.0.3) ist, dass sein Verhalten nicht dem der Breite entspricht: X%; Soweit wir sehen können, erfolgt "calc" zum Zeitpunkt des ersten Renderns in ein statisches Xpx. Dies bedeutet, dass im Gegensatz zu width: X% die Größe der berechneten Spalte nicht automatisch mit der Containergröße geändert wird.
Pancho
16

Ich denke wir könnten eine haben box-sizing: margin-box. Das CSS-Box-Modell zeigt genau, wie die Ränder der Frames positioniert sind.

Es gibt kleinere Probleme - zum Beispiel können sich die Randfelder überlappen - aber sie sind nicht schwer zu lösen.

Ich denke, die Situation ist die gleiche, wie wir mit dem overflow-x& sehen könnenoverflow-y -Kombinationen sehen können, bei den absolut positionierten Divs in Tabellenzellen, bei der Kombination von min | max-width | height mit der Box-Größe und so weiter.

Es gibt Funktionen, wirklich einfache Funktionen, die die Browserentwickler einfach nicht entwickeln.

IMHO, box-sizing: margin-boxwaren eine sehr nützliche Funktion. Ein weiteres nützliches Feature war das box-sizing: padding-box, es existiert zumindest im Standard, wurde aber in keinem der gängigen Browser implementiert. Nicht einmal im neuesten Chrom!


Hinweis: @Oriols Kommentar: Firefox hat Box-Sizing: Padding-Box implementiert. Aber andere nicht, und es wurde aus der Spezifikation entfernt. Firefox wird es in Version 50 entfernen. Traurig.

Peter - Setzen Sie Monica wieder ein
quelle
2
Firefox hat implementiert box-sizing: padding-box. Aber andere nicht, und es wurde aus der Spezifikation entfernt. Firefox wird es in Version 50 entfernen. Traurig.
Oriol
6

Der Typ oben fragt nach dem Hinzufügen eines Randes zur Gesamtbreite, einschließlich Polsterung und Rand. Die Sache ist, Rand wird außerhalb der Box angewendet und Polsterung und Rand sind nicht, wenn verwendet border-box.

Ich habe versucht, die border-marginIdee zu erreichen . Ich habe festgestellt, dass Sie bei Verwendung von margin entweder .lastdem letzten Element eine Klasse von hinzufügen können (mit margin, dann einen Rand von Null anwenden oder verwenden):last-child/:last-of-type ). Oder fügen Sie rundum gleiche Ränder hinzu (ähnlich der obigen Polsterversion).

Beispiele finden Sie hier: http://codepen.io/mofeenster/pen/Anidc

border-boxberechnet die Breite des Elements + seine Auffüllung + seinen Rand als Gesamtbreite. Wenn Sie also 2 divs haben, die 50% breit sind, sind sie benachbart. Wenn Sie 8pxihnen Polster hinzufügen , haben Sie eine Rinne von 16px. Kombinieren Sie dies mit einem Wickelelement - das auch gepolstert ist 8px- Sie erhalten ein schön angelegtes Gitter mit gleichmäßigen Rinnen ringsum.

Sehen Sie dieses Beispiel hier: http://codepen.io/mofeenster/pen/vGgje

Letzteres ist meine Lieblingsmethode.

Morgan Feeney
quelle
4

Ich bin mir sicher, dass dies alles offensichtlich ist, aber ich werde es trotzdem abtippen, weil ... nun, ich brauche die Übung. Wäre das folgende Ergebnis nicht genauso effizient wie box-sizing: margin-box;:

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizingwird verwendet, um zu steuern, ab welchem ​​Punkt die Polsterung und der Rand auf die Gesamtgröße des Elements bewertet werden. Obwohl es nicht koscher ist, pxRänder mit einer %Breite einzuschließen (wie dies normalerweise immer der Fall ist), ist es einfacher zu berechnen, wie hoch der relative Prozentsatz sein sollte, da Sie keine Auffüllungen und Ränder in die definierte Breite einfügen müssen.

Stehlager
quelle
9
Der Anwendungsfall für so etwas wie eine Randbox besteht darin, das Mischen von prozentualen Breiten mit Pixelrändern zu ermöglichen. Wenn Sie zwei 50% -Felder mit einem Abstand von 1 Pixel möchten, kann dies nicht mit einem prozentualen Abstand von 1% erreicht werden. Einige kleine Bildschirmgrößen runden 1% auf 0 Pixel ab, und plötzlich haben Sie keinen Rand mehr. Was wir wirklich brauchen, ist mehr Browserunterstützung für calc (), wie @Slouch zeigt, oder das Flexbox-Modell.
1
Wenn das die Sorge ist, würde der übergeordnete Container weniger als 100 Pixel groß sein, und ich würde hoffen, dass einige Designelemente an diesem Punkt überdacht werden. Es gibt einige andere Dinge, die Sie mit verschachtelten Elementen und dergleichen tun könnten, aber ja, variable Berechnungen wären ziemlich dumm. Wenn Sie sich für Dinge wie Sass oder weniger interessieren, denke ich, dass sie viel von diesem Zeug machen. Ich habe mit ihnen herumgespielt, bin aber noch kein Jedi.
Stehlager
2
Was Sie vorschlagen, ist eine Umgehung. Es ist keine ideale Möglichkeit, CSS zu schreiben, wenn Sie mit komplexen Layouts arbeiten. Sie gehen davon aus, dass der Designer oder Autor Prozentsätze in seinem Design verwenden möchte. Unabhängig von diesem Problem wird der Designer auch dann eingeschränkt, wenn Sie die Funktion calc () verwenden, um den Abstand mithilfe von Pixelrändern zu ermitteln, da er die Rinne vorab festlegen muss, anstatt sie mit CSS überschreiben zu lassen.
Limitlessloop
Ich verstehe deinen Standpunkt nicht. Das Problem bestand darin, dass das Einbeziehen von px und% Zeilenumbrüche verursacht, da der Rand nicht in die Größenberechnung einbezogen wird. Ein Rand ist nicht in der Größe eines Elements enthalten, sondern der Bereich, den Sie um ein Element herum anzeigen möchten. Wie würde man margin-boxmit mehrdimensionalen Randberechnungen umgehen? @mediaHaltepunkte max-widthund min-widthfunktionieren einwandfrei. Ich denke, ich margin-boxkönnte etwas Aufblähen reduzieren, aber ich bekomme auch Gründe, warum es als überflüssig angesehen werden kann.
Plummer
Warum erwähnt niemand, dass dieser Rand Prozentwert der Prozentsatz der Breite aus irgendeinem Grund ist ... spielt keine Rolle für Höhe oder Breite. Die Breite des übergeordneten Elements wird verwendet. Was gelinde gesagt bizarr ist. Der obige Code sollte also nicht funktionieren und funktioniert nicht. es sei denn, Sie machen Höhe und Breite gleich.
Muhammad Umer
4

Dies liegt daran, dass sich das Attribut "Box-Sizing" auf die Größe eines Elements bezieht, nachdem die angegebenen dimensionsspezifischen Werte (Auffüllen, Rahmen) berechnet wurden. "box-sizing: border-box" legt die Höhe / Breite eines Elements fest und berücksichtigt sowohl die Polsterung als auch die Rahmenbreite. Der Umfang des Randes eines Elements ist größer als der des Elements selbst. Dies bedeutet, dass der Seitenfluss und die umgebenden Elemente geändert werden und somit die Art und Weise, wie das Element in das übergeordnete Element passt, relativ zu den Geschwisterelementen direkt geändert wird. Letztendlich würde ein "Randfeld" -Attributwert große Probleme verursachen und entspricht im Wesentlichen dem direkten Einstellen der Höhe / Breite der Elemente.

Ryan
quelle
1
Ich entschuldige mich, aber ich verstehe nicht, wie sich die Einbeziehung von Polsterung, Rand und Rand in die räumliche Berechnung über "Randbox" konzeptionell von der Einbeziehung von Polsterung und Grenze über "Randbox" unterscheiden würde. Sicher ist es nur eine Variation des gleichen Themas?
Pancho
1

Auf Codrops gibt es einige gute Artikel zum Thema der Auswirkung von Rändern und Zeilen, die zum Überlaufen gezwungen werden. Sie empfehlen, die Rem- oder Em-Einheit mit einem Normalisierer-CSS zu verwenden, der die Schriftgröße für alle Browser auf 100% einstellt. Wenn Sie dann Breiten und Ränder festlegen, können Sie den Effekt auf die Zeilenbreite leicht verfolgen, indem Sie einfach in den Kommentaren für eine Notiz für machen die Gesamtbreite. Eine Konvertierung von 16px in 1 em ist der Weg, um die Gesamtanzahl der Zielansichtsfenster mit zu berechnen.

Arbeiten Sie zumindest für die Entwicklungsphase so. Wenn Sie dann reaktionsschnelle Vorlagen wünschen, können Sie die Breiten einschließlich der Randbreiten in% konvertieren.

Die andere und oft einfachere Art, mit Dachrinnen umzugehen, besteht darin, das Pseudo-After und das content: '';auf jeder Ihrer Spalten zu verwenden, was meiner Meinung nach sehr gut funktioniert. Wenn Sie eine div-Klasse festlegen, die die definierte letzte Spalte ist, z. B. end, können Sie darauf abzielen, dass diese Klasse kein Pseudo nach oder eine breitere hat. was immer am besten zu Ihrem Layout passt.

Der zusätzliche Vorteil dieser Pseudo-Element-Methode besteht darin, dass Sie auch ein Ziel für Schatten erhalten, die dem flachen Bild auf dem Lesemonitor einen 3D-Effekt und eine größere Tiefe verleihen können. Ich experimentiere gerade mit diesem Effekt, indem ich die auf Schaltflächen verwendeten Effekte vergrößere, die Verläufe und den Z-Index 'optimiere'.

Weedy101
quelle
1

Die Abmessungen von nicht ersetzten Elementen auf Blockebene im normalen Durchfluss müssen übereinstimmen

Rand-links + Rand-links-Breite + Auffüllen-links + Breite + Auffüllen-rechts + Rand-rechts-Breite + Rand-rechts = Breite des enthaltenen Blocks

Bei übermäßigen Einschränkungen müssen Browser entweder den linken oder den rechten Rand anpassen. Ich glaube, bedeutet die Breite des Randfeld muss die Breite des umschließenden Blocks gleich sind (dh 100%).

In Ihrem Fall können transparente Ränder mit box-sizing: border-boxähnlich wie Ränder funktionieren .

Sam
quelle
1

Stellen Sie den Rand möglicherweise mit RGBA auf 0% Deckkraft ein und verwenden Sie den Rand als Rand.

user3236407
quelle
Klingt nach einem Hack, würde aber den Job machen.
Morgan Feeney
Dies kann sich als nützlich erweisen, wenn Sie keine Wrapper verwenden möchten, um den Auftrag auszuführen.
Limitlessloop
... es sei denn, Sie brauchen tatsächlich eine Grenze
FrancescoMM
@FrancescoMM - ein bisschen "laut", aber Sie könnten ein Feld mit einem transparenten Rand "Randbreite" (und natürlich ohne Rand) erstellen und darin ein Feld mit einem sichtbaren Rand der gewünschten Breite platzieren (wieder ohne Rand)
Pancho
1
Ich kann dieser Art des Denkens einfach nicht folgen. Gibt es etwas Natürlicheres als zu sagen, dass ich zwei Boxen 1pxauseinander haben möchte , von denen jede den 50%verfügbaren Platz einnimmt? Genau das margin-boxwürde tun. Oder vergessen Sie die Randbox und denken Sie über den verfügbaren Platz nach. Nicht 50% des übergeordneten Containers, sondern 50% der verbleibenden Teile. Kein "calc", kein "5% margin", kein solches Durcheinander ...
maaartinus
0

Es gibt eine interessante Situation bei der Verwendung von Box-Sizing innerhalb des Körperinhalts

Kein Inhalt Kein Rahmenfeld gibt keinen Wert für den linken / rechten Rand an.% Nachzählung dieser beiden Box-Nachzählungsalgorithmen

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

Firefox-Versionen vor 57 unterstützten auch den Padding-Box-Wert für die Box-Größe, obwohl dieser Wert aus der Spezifikation und späteren Versionen des Browsers entfernt wurde.

Also Margin-Box auch nicht geplant ...

Dmytro Yurchenko
quelle