Abschnitt 4 · Lektion 2
box-sizing
An einem Element steht width: 300px, und nachgemessen ist es 350 Pixel breit. Der Browser rechnet dabei nicht falsch. Er hält sich an seinen eingebauten Standard, und der kostet beim ersten Mal gern einen halben Nachmittag.
Woher die zusätzlichen Pixel kommen
Der Standard heißt content-box und nimmt width beim Wort. Die Angabe meint den Inhalt, also den innersten der vier Ringe. Innenabstand und Rahmen liegen außen herum und kommen dazu.
Bei 300px Breite, 24px Innenabstand auf beiden Seiten und 1px Rahmen auf beiden Seiten ergibt das 300 plus 48 plus 2, also 350.
<div class="spalte">
<div class="karte">Tipptrainer</div>
<div class="karte">Referenz</div>
</div> /* Die Spalte ist 640px breit, jede Karte bekommt 300px.
300 und 300 sind 600, es müsste also bequem passen. */
.spalte {
width: 640px;
background-color: #fef9c3;
}
/* content-box ist der Standard: width meint nur den Inhalt.
Innenabstand und Rahmen kommen obendrauf, macht 350px. */
.karte {
display: inline-block;
vertical-align: top;
width: 300px;
padding: 24px;
border: 1px solid #d4d4d8;
background-color: #ffffff;
} Die Spalte ist 640px breit. Zwei Karten mit je 300px sollten da locker hineinpassen. Zusammen sind sie aber 700px breit, und die zweite rutscht in die nächste Zeile.
Das Tückische daran ist, dass die Rechnung im Kopf stimmt. Du hast dich nicht verrechnet, du hast nur eine andere Zahl gemeint als der Browser.
Nachmessen kannst du das direkt am Beispiel. Im Inspector steht an einer der Karten im Auskunftsstreifen oben 350 × 69 und ein Stück weiter unten width: 300px, also zwei verschiedene Zahlen an derselben Karte. Die obere ist der Platz, den der Kasten wirklich einnimmt. Die untere ist die Zahl, die du hingeschrieben hast. Was dazwischen liegt, steht auch im Streifen, nämlich padding: 24px auf beiden Seiten und border: 1px solid rgb(212, 212, 216). Macht 48 plus 2.
border-box rechnet mit
Mit box-sizing: border-box bedeutet width die Gesamtbreite aus Inhalt, Innenabstand und Rahmen. Der Inhalt schrumpft entsprechend, statt dass der Kasten wächst.
<div class="spalte">
<div class="karte">Tipptrainer</div>
<div class="karte">Referenz</div>
</div> .spalte {
width: 640px;
background-color: #fef9c3;
}
/* Eine einzige Zeile Unterschied. Jetzt sind die 300px
die Gesamtbreite, Innenabstand und Rahmen inklusive. */
.karte {
box-sizing: border-box;
display: inline-block;
vertical-align: top;
width: 300px;
padding: 24px;
border: 1px solid #d4d4d8;
background-color: #ffffff;
} Eine Zeile Unterschied, und die beiden Karten passen nebeneinander. Im Auskunftsstreifen stimmen die beiden Zahlen jetzt überein, oben 300 × 69 und unten width: 300px. In der Zeile box-sizing steht statt content-box jetzt border-box. Der Text hat innen etwas weniger Platz, weil die 48px Innenabstand von den 300 abgehen. So war die Zahl ja auch gemeint.
Der Außenabstand bleibt übrigens in beiden Modi außen vor. box-sizing betrifft nur die drei inneren Ringe, margin kommt immer obendrauf.
Der Reset
border-box ist in praktisch jeder Situation das, was man meint. Deshalb stellt man es nicht an einzelnen Elementen ein, sondern global.
<div class="kasten">Hier stimmt jede Breite, die du hinschreibst.</div> /* Diese fünf Zeilen stehen am Anfang fast jedes Stylesheets.
Die Pseudoelemente sind mit dabei, weil auch erzeugte
Inhalte eigene Kästen sind (Lektion 2.6). */
*,
*::before,
*::after {
box-sizing: border-box;
}
.kasten {
width: 240px;
padding: 16px;
border: 4px solid #2563eb;
background-color: #dbeafe;
} Der Universalselektor kostet dabei nichts an Spezifität, denn * zählt null (Lektion 3.2). Passt die Einstellung an einem Element mal nicht, lässt sie sich dort ohne Mühe überschreiben.
Die beiden Pseudoelemente stehen mit in der Liste, weil * sie nicht erfasst. Sie sind eigene Kästen mit eigenem Innenabstand und eigenem Rahmen, und die sollen nach derselben Regel rechnen.
Eine einzige Regel am html-Element würde nicht reichen, denn box-sizing vererbt sich nicht. Es gehört zu den Kasten-Eigenschaften aus Lektion 3.3, und die bleiben da, wo sie stehen. Wer wirklich jedes Element erwischen will, kommt am Universalselektor also nicht vorbei.
Ich setze diesen Block an den Anfang jeder Datei. Danach meint jede Breitenangabe genau das, was dasteht.
Warum das nicht von Anfang an so war
content-box steht so in der ersten CSS-Spezifikation von 1996. Ändern lässt sich das nicht mehr, denn jede Seite, die seither gebaut wurde, rechnet damit.
Kurios ist, dass die alten Versionen des Internet Explorer es damals anders gemacht haben, und aus heutiger Sicht sogar besser. Sie rechneten wie border-box, und das galt jahrelang als der Fehler, um den man herumbauen musste. Mit CSS3 kam die Eigenschaft, und der bequemere Modus bekam einen Namen. Seitdem ist er der Standard, den man sich selbst einschaltet.
In der Aufgabe passen zwei Felder rechnerisch nebeneinander in ihr Formular und stehen trotzdem untereinander.
Zum Mitnehmen
Mit border-box meint width die ganze Breite samt Innenabstand und Rahmen. Der Reset mit * und den beiden Pseudoelementen stellt das für jedes Element um, weil box-sizing sich nicht vererbt.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.