Zum Inhalt
wannacode

Das Box-Modell

Kurz gesagt: Das Box-Modell sagt, dass jedes Element eine Box aus Inhalt, Innenabstand, Rahmen und Außenabstand ist; mit box-sizing: border-box gehören Innenabstand und Rahmen zur Breite.

Problem

Die Karten ragen aus dem Bildschirm

Die Seite mit den Broten auf einem Handy mit 360px Breite. Jede Karte hat width: 100%: so breit wie die Spalte. Trotzdem ragen die Karten rechts heraus, und die ganze Seite rutscht zur Seite.

HTML, CSS, JS

Die Spalte ist 360 − 2 × 16 = 328px breit. So breit sollte die Karte sein, und sie ist 362px breit: 34px breiter als die Spalte. Diese 34px sind kein Fehler in der Zahl 100%. Sie stecken in dem, was width misst.

Die Idee

Vier Schichten

Für CSS ist jedes Element eine rechteckige Box. Sie hat vier Schichten, von innen nach außen:

  • der Inhalt: der Text, das Bild, die Kinder;
  • padding (Innenabstand): der Platz zwischen dem Inhalt und dem Rahmen. Der Hintergrund des Elements füllt ihn;
  • border (Rahmen): die Umrandung;
  • margin (Außenabstand): der Platz außerhalb des Rahmens, bis zu den benachbarten Boxen. Er ist durchsichtig.

Standardmäßig ist width nur die Breite des Inhalts. Innenabstand und Rahmen kommen außen dazu, auf beiden Seiten:

.card {
width: 100%; /* 328px: der Inhalt */
padding: 16px; /* + 2 × 16 */
border: 1px solid #ccc; /* + 2 × 1 = 362px */
}

Deshalb ist die Karte vom Anfang 362px breit. padding: 16px gilt für alle vier Seiten. Du kannst sie auch einzeln setzen: padding: 8px 16px (oben und unten, links und rechts) oder padding-left: 16px.

Sieh es dir an

Sieh dir die Box an

Die Box wird Schicht für Schicht aufgebaut. Die Zeile oben ist width: Achte darauf, was sie misst.

/* Standard: box-sizing: content-box */
.card {
width: 280px;
padding: 24px;
border: 8px solid #2b3a55;
margin: 16px;
}
.card.bb {
box-sizing: border-box;
}
Schritt für Schritt, in Worten
  1. In der Mitte steht der Inhalt: der Text der Karte. Standardmäßig ist width nur die Breite des Inhalts: 280px.
  2. padding ist der Platz zwischen dem Inhalt und dem Rahmen. Er liegt auf beiden Seiten: 280 + 2 × 24 = 328px. Auch der Hintergrund der Karte füllt ihn.
  3. border ist der Rahmen, ebenfalls auf beiden Seiten. Die Box ist jetzt 344px breit, nicht 280: width hat nicht gesagt, wie breit die Karte auf dem Bildschirm ist.
  4. margin ist der Platz außerhalb des Rahmens, zwischen dieser Box und der nächsten. Er hat keinen Hintergrund und gehört nicht zur Karte, nimmt aber Platz weg: 376px.
  5. box-sizing: border-box ändert, was width bedeutet: Es ist jetzt die Breite bis zum Rahmen. Die Karte ist 280px breit, und der Inhalt schrumpft auf 280 − 48 − 16 = 216px.
  6. Dasselbe CSS, zwei Bedeutungen von width. Mit content-box ist die Karte 344px breit, mit border-box 280px: so viel, wie width sagt. Deshalb setzt fast jedes Projekt border-box für alle Elemente.

Dieselben zwei Karten im Browser. Das Blaue ist der Absatz darin: Er ist so breit wie der Inhalt der Karte. Wähl in den Entwicklertools (F12) die Karte aus: Das Panel Berechnet zeichnet dieselbe Box mit den Zahlen jeder Schicht.

HTML, CSS, JS

Die Idee

box-sizing: border-box

Im Kopf zu rechnen erzeugt Fehler: Du willst eine Karte so breit wie die Spalte und musst Innenabstand und Rahmen abziehen. box-sizing: border-box ändert, was width bedeutet: Es ist die Breite bis zum Rahmen einschließlich. Innenabstand und Rahmen werden von innen abgezogen, und der Inhalt schrumpft.

Dann ist width: 100% wirklich die Spalte, egal wie groß der Innenabstand ist. Deshalb beginnt fast jedes Projekt mit:

*, *::before, *::after {
box-sizing: border-box;
}

* trifft jedes Element. box-sizing wird nicht vererbt, deshalb gilt die Regel für alle Elemente, nicht nur für <html>. ::before und ::after sind Inhalte, die CSS selbst hinzufügt; auch sie sind Boxen.

Probier es aus

Lass die Karten passen

Sorg mit box-sizing: border-box dafür, dass die Karten auf den Handy-Bildschirm passen. Der Innenabstand (16px) und der Rahmen (1px) bleiben.

HTML, CSS, JS

Die Regel, mit der fast jedes Projekt beginnt:

*, *::before, *::after {
  box-sizing: ;
}

Die Idee

Außenabstände verschmelzen

Zwei Boxen untereinander: Der untere Außenabstand der oberen und der obere Außenabstand der unteren Box addieren sich nicht. Sie verschmelzen, und der größere bleibt.

HTML, CSS, JS
  • Die Hinweise haben 24px unten und 16px oben. Zwischen ihnen liegen 24px, nicht 40px.
  • Die Überschrift im Banner hat margin: 20px 0. Der Banner hat oben weder Innenabstand noch Rahmen, deshalb tritt der Außenabstand der Überschrift darüber heraus: Der orange Hintergrund beginnt direkt über dem Text. Mit padding: 1px 16px am Banner deckt der Hintergrund den Außenabstand mit ab.

Nur vertikale Außenabstände verschmelzen. Links und rechts addieren sie sich immer. In Flex und Grid, den nächsten Lektionen, verschmelzen auch vertikale nicht.

Die Idee

block, inline und inline-block

Nicht jede Box verhält sich gleich. Die Eigenschaft display sagt, wie eine Box sich zwischen den anderen einordnet.

  • block: beginnt in einer neuen Zeile und nimmt die volle Breite des Elternelements ein. Breite, Höhe, Außenabstand und Innenabstand gelten. div, p, h1 und article sind so.
  • inline: steht in der Textzeile und ist so breit wie ihr Inhalt. Breite und Höhe gelten nicht, ein vertikaler Außenabstand bewegt nichts, und ein vertikaler Innenabstand wird gemalt, schiebt die Zeilen aber nicht auseinander. span, a und strong sind so.
  • inline-block: steht wie inline in der Zeile, aber Breite, Höhe, Außenabstand und Innenabstand gelten wie bei block.
HTML, CSS, JS

Die zwei Labels haben dieselben Eigenschaften, und das zweite ist zusätzlich inline-block. Das erste ist inline: width: 64px und der Außenabstand gelten nicht, und das Rot des Innenabstands ragt über und unter der Zeile heraus, ohne sie von den anderen wegzuschieben. Das zweite ist inline-block: Es ist 64 + 2 × 8 = 80px breit (hier ist es noch content-box), und der Absatz wird höher, damit es hineinpasst.

Probier es aus

Die Labels

Die Labels −20% und Neu sollen je 64px breit sein und nebeneinander in einer Zeile stehen. Im Moment gilt die Breite nicht.

HTML, CSS, JS

Die Idee

Einheiten

Bisher stand alles in px. CSS hat noch andere Einheiten, und jede ist für etwas gut:

  • px: ein fester Wert. Gut für Rahmen und kleine Abstände.
  • rem: die Schriftgröße von <html> (16px, wenn niemand sie geändert hat). 1.5rem sind überall auf der Seite 24px. Wenn jemand in den Browsereinstellungen die Schrift vergrößert hat, wächst rem mit und px nicht. Schriften und Abstände stehen deshalb am besten in rem.
  • em: die Schriftgröße des Elements selbst; in font-size die des Elternelements. Ein Innenabstand in em wächst mit dem Text eines Buttons.
  • %: vom Elternelement. width: 50% ist die halbe Breite des Inhalts des Elternelements.
  • vw und vh: 1% der Breite und der Höhe des Fensters.
HTML, CSS, JS

Die Überschrift hat 1.5rem = 24px. Die Karte ist 50% von 320px = 160px breit. Ihre Schrift ist 18px, also sind padding: 1em 18px. 1.25rem an der Überschrift in der Karte sind 20px: rem kümmern die 18px der Karte nicht. 0.75em an <small> kommt von der Schrift des Absatzes, die 18px geerbt hat: 13,5px.

Probier es aus

Finde den Fehler

Das Menü hat 20px, das Untermenü darin 25px, und die nächste Ebene ist noch größer. Welche Zeile ist schuld?

Wähle die Zeile mit dem Fehler.

Genauer, für Neugierige

Prozentwerte bei padding und margin beziehen sich auf die Breite des Elternelements, auch oben und unten. padding-top: 50% macht eine Box halb so hoch, wie ihr Elternelement breit ist.

100vw und die Bildlaufleiste. vw schließt die Bildlaufleiste ein. Wenn die Seite eine sichtbare vertikale Bildlaufleiste hat, ist ein Element mit width: 100vw breiter als die Seite und löst horizontales Scrollen aus. Für „die volle Breite“ ist width: 100% sicherer.

vh auf dem Handy. Die Adressleiste erscheint und verschwindet. 100vh ist die Höhe bei versteckter Leiste, deshalb liegt der untere Rand bei sichtbarer Leiste unter dem Bildschirm. 100dvh folgt der tatsächlichen Höhe im Moment.

outline wird wie ein Rahmen gezeichnet, nimmt aber keinen Platz weg und verschiebt nichts. Deshalb zeigt man damit den Fokus von Buttons.

min-width und max-width setzen Grenzen: max-width: 100% verhindert, dass ein Bild aus der Spalte ragt.

Formulare. In Chromium sind Buttons standardmäßig border-box, Felder (input) dagegen content-box. Die Regel mit * macht sie gleich.

Wie man das Verschmelzen verhindert. Der Außenabstand eines Kindes tritt nicht durch das Elternelement hindurch, wenn das Elternelement oben Innenabstand oder einen Rahmen hat oder display: flow-root ist. So schafft das Elternelement einen neuen Layoutkontext (Block Formatting Context).

Ein negativer Außenabstand zieht die Box nach außen und überlappt sie mit ihren Nachbarn. Du brauchst ihn selten.

Übung

Der Katalog auf dem Handy

Der Katalog auf einem Handy (360px). Setz border-box auf alle Elemente, damit die Karten auf den Bildschirm passen. Die Karte: padding 1rem, ein Rahmen 1px solid #ddd und 12px Platz unter jeder. Die Produktüberschriften haben 1.25rem. Die Labels −20% und Neu sind inline-block, mit padding 2px 8px, weißem Text und rotem Hintergrund (#c0392b). Der Button ist so breit wie das Innere der Karte: width: 100%.

HTML, CSS, JS

Test

Teste dich

1. .box { width: 200px; padding: 10px; border: 2px solid; } ohne box-sizing. Wie breit ist die Box auf dem Bildschirm?
2. Dieselbe Regel mit box-sizing: border-box. Wie breit ist der Inhalt?
3. Ein Absatz hat margin-bottom: 30px, der nächste margin-top: 20px. Wie weit sind sie voneinander entfernt?
4. <html> hat 16px und das Elternelement 20px. Wie groß ist font-size: 1.5rem im Kind?
5. Warum bewirkt width: 80px bei einem <span> nichts?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·