CSS/Tutorials/Boxmodell
Mit CSS können Sie jedoch Größenangaben und Abstände festlegen. Was auf unserem Symbolbild wie ein Unfall aussieht, zeigt eigentlich nur, wie viele Möglichkeiten CSS bietet.
- „klassisches“ Boxmodell
- box-sizing
- Größenangaben
- extrinsisch
- width, max-width + min-width
- height, max-…
- intrinsische Werte
- max-content, min-content
- fit-content()
- extrinsisch
- übergroßer Inhalt
- overflow
- text-overflow
- scroll
- Außen- und Innenabstand
- zusammenfallende Außenabstände
(collapsing margins)
- padding
- zusammenfallende Außenabstände
- Logische Eigenschaften
- block-size und inline-size
- margin-block + margin-inline
- padding-block + padding-inline
- padding-block + padding-inline
- Rahmen und Ribbons
- Wichtiges mit Rahmen hervorheben
- Ribbons (Hintergrundbänder)
- box-shadow und filter
Das „klassische“ Boxmodell
- 20min
- einfach
- Einstieg in CSS
Die rechteckigen Blöcke, die im Elementbaum erzeugt und auf dem Bildschirm dargestellt werden, folgen einem Schema, dem „Box-Modell“. Es ist somit Grundlage jeden Layouts.
Jedes Block-Element wie Textabsätze (p), -Abschnitte (div, article, main, aside, …) und Überschriften (h1, h2, …) bildet eine rechteckige Box, die Sie frei formatieren können.
Im CSS-Einstieg haben wir Überschriften oft eine Text-und Hintergrundfarbe zugewiesen. Im folgenden Beispiel wollen wir die um Randlinien und Abstände erweitern:
h1 {
color: midnightblue;
background-color: yellow;
border: 1px solid;
margin: 0;
padding: 0;
}
.box {
width: 200px;
color: green;
background-color: lightyellow;
border: 2px solid red;
border-radius: 0 1em 1em 1em;
margin: 20px auto;
padding: 2em;
}
Im Beispiel erhalten Überschrift h1 und Textabsatz p zusätzlich mit border noch eine Randlinie. Die Eigenschaft ist eine zusammenfassende „shorthand“-Eigenschaft der drei Werte für die Randstärke border-width, die Form border-style und den optionalen Wert für die Randfarbe border-color. Wird dort kein Wert zugewiesen, wird die Textfarbe des Elements verwendet.
Mit margin können Sie einen Abstand zum Elternelement und benachbarten Elementen festlegen. Die Überschrift „klebt“ durch margin: 0;
am oberen Rand der Seite. Der Textabsatz erhält mit margin: 20px auto;
einen Abstand von 20px nach oben (und unten), sowie mit auto
einen gleichmäßig verteilten Abstand nach rechts und links. In Verbindung mit der Festlegung für die Breite width: 200px;
wird der Textabsatz zentriert.
Die Überschrift stößt fast gegen die Randlinie; der Textabsatz hat mehr Platz. Das erreichen Sie durch eine Angabe eines Innenabstands padding (engl. für Polsterung)
- Betrachten Sie das Beispiel im Frickl (einfacher Klick auf "Ausprobieren").
- Verändern Sie im Frickl die Werte für Breite, Höhe, Randlinien und Abstände. Was beobachten Sie?
Alle diese Eigenschaften verwenden Längenangaben. Dabei können Sie absolute Werte in Pixel, aber auch relative Werte wie Prozentangaben und die Längeneinheit em, die die Größe der verwendeten Schriftart als Basisschriftgröße verwendet, verwenden.
padding oder margin?
Es wird oft gefragt, welche der beiden Eigenschaften man verwenden soll – padding oder margin?
- Wenn die Box eine eigene Hintergrundfarbe hat, soll der Rand um den Inhalt mit gefärbt sein (padding) oder nicht (margin)? Oder gar beides?
- margins können überlappen (→ Collapsing margins). D.h. wenn ich zwei Boxen übereinander habe, und beide haben
margin: 2em
, dann ist der Abstand zwischen den Boxen 2em, nicht 4em.
Rechtecke nebeneinander
Damit Text auf unserer Webseite gut lesbar ist, wollen wir ein Drei-Spaltenlayout entwerfen. Die Seite erhält eine feste Breite von 600px, die drei Spalten von je 200px.
.container {
width: 600px;
height: 400px;
border: 1px solid;
padding: 0;
}
.spalte {
width: 200px;
height: 200px;
border: 1px solid red;
margin: 5px;
padding: 5px;
display: inline-block;
}
Das Beispiel zeigt unerwünschtes Verhalten:
- Warum werden die drei Boxen nicht nebeneinander dargestellt? Ein Blick in den Seiteninspektor (erreichbar mit F12) zeigt uns, dass die Spalten aus Boxen mit je 200px Breite, einer Randlinie von 1px und einem Innen- und Außenrand von je 5px, also ingesamt einer Gesamtbreite von 222px bestehen:
- Die Boxen haben zu wenig Platz und ragen über die Elternelemente heraus: Obwohl das Container-Element eine vermeintlich ausreichende Höhe von 200px hat, ragen die beiden ersten Blöcke teilweise und der dritte Block ganz aus dem von uns falsch berechneten Rechteck heraus.
- Im Frickl beträgt der Viewport des Beispiels weniger als die angegebenen 600px Breite, sodass ein horizontaler Scrollbalken erscheint.
Theorie: das klassische Box-Modell
Wie im oben gezeigten Beispiel demonstriert, werden im Box-Modell alle Bestandteile einer Box addiert. Die Gesamtbreite errechnet sich aus:
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
Die Gesamthöhe einer Box wird ebenso errechnet.
In dieser interaktiven Demo können Sie die verschiedenen Möglichkeiten ausprobieren:
Fazit: Beim Layout müssen Sie zur angegebenen Breite alle Abstände und die Stärke der Randlinien dazurechnen, da dies die tatsächliche Breite des Block-Elements ergibt. Die mühselige Rechenart wurde früher weiter erschwert, da der Internet Explorer in den Versionen 5 und 5.5 einen als Box-Model-Bug bekannten Fehler hatte. Durch diesen Fehler wurden die Maße einer Box falsch berechnet: Die Maße für Rahmen und Innenabstände wurden nicht zu Breite und Höhe addiert, sondern davon abgezogen.
Dieser Fehler wurde in Version 6 behoben, jedoch im Quirks-Modus beibehalten. Das bedeutete, dass der Box-Modell-Fehler auch in neueren Internet Explorer Versionen auftrat, wenn nicht der standardkonforme Modus verwendet wurde.
Theorie 2: Box ist nicht gleich Box
Eine Box hat zwei Darstellungsaspekte: die Außensicht und die Innensicht. Bei der Außensicht unterscheidet man zwischen Inline- und Block-Boxen, die Innensicht behandelt die diversen Layoutmodelle, die CSS anbietet. Jedes HTML Element ist entweder eine Inline- oder Block-Box. Die CSS Display Level 3 Spezifikation definiert auch eine Run-In Box, die aber (Stand 2022) nur der Internet Explorer kannte und auf die nicht eingegangen werden soll.
Das defaultmäßige Layoutmodell für fast alle Boxen ist flow, d.h. Inline-Boxen werden nebeneinander und Block-Boxen untereinander gesetzt. Ausnahme davon ist das table-Element mit seinen Kind-Elementen und das ruby-Element. Eine weitere Ausnahme entsteht, wenn für eine Box ein neuer Blockformatierungskontext gebildet wird, in diesem Fall lautet das Layout-Modell flow-root, was Auswirkungen auf das Verhalten von Rändern oder Floats hat.
Eine Box, deren Layoutmodell Flow (oder Flow-Root) ist, wird auch ein Block Container genannt. Diese Definition ist wichtig, denn einige CSS-Eigenschaften sind nur auf Block Container anwendbar. Andere Layoutmodelle sind Table, Flexbox, Grid und Ruby.
Sie können diese Darstellungsaspekte mit der CSS-Eigenschaft display festlegen. Die klassischen Werte inline
oder block
bezeichnen eine Inline- oder Block-Box mit Flow-Layout, ggf. auch flow-root Layout. Der Wert inline-block
bezeichnet eine Inline-Box mit flow-root Layout, wodurch das Innenverhalten eines Blocks entsteht.
Theorie 3: Nicht ersetzte Inline-Boxen
Dieser Begriff ist für etliche CSS Eigenschaften von Bedeutung, denn bestimmte Effekte können auf solche Boxen nicht angewendet werden. Was ist hier gemeint?
- Nicht ersetzt
- Manche Elemente werden ersetzt. Ihr Inhalt ist für CSS nicht zugänglich, er stammt aus einer anderen Quelle. Das kann ein Bild oder ein Video sein, ein iframe, mit
<embed>
eingebetteter Inhalt, je nach Kontext auch ein Audio-Element, ein Canvas oder ein object-Element. - Nicht ersetzte Elemente können in ihrem inneren Erscheinungsbild mit CSS beeinflusst werden
- Inline
- Eine Box ist inline, wenn sie im normalen Elementfluss eingeordnet wird und an einem Zeilenende auch umgebrochen werden kann.
Bei nicht ersetzten Inline-Boxen sind CSS-Eigenschaften wie beispielsweise width, height oder transform nicht anwendbar.
modernes WebDesign
Um die Jahrtausendwende mussten WebDesigner mit Papier und Bleistift Breiten und Abstände zusammenrechnen, um ein pixelgenaues Layout für eine feste Größe von 640x480px (später auch 1024x768px) zu erstellen. Heute ist dies nicht mehr nötig:
Lösung 1: Das alternative Boxmodell
Mit CSS3 wurde das starre Konzept des Boxmodells angepasst. Mithilfe der Eigenschaft box-sizing lässt sich spezifizieren, worauf sich die Angaben von width
bzw. height
beziehen sollen.
* {
box-sizing: border-box;
}
article {
width: 40em;
border: 2px solid;
display: table:
}
section, aside {
width: 33.333%;
border: 1px solid red;
margin: 0;
padding: .5em;
display: table-cell;
}
Durch box-sizing: border-box werden Innenabstand und Randlinie nun ohne weitere Berechnung von uns durch den Browser bei der Breitenberechnung berücksichtigt.
Bei der Verwendung von display:inline-block bilden sich kleine Abstände zwischen den Elementen. Durch die Verwendung von display:table für das Elternelement und display:table-cell für die Kindelemente können die drei Spalten direkt nebeneinander wie in einer Tabelle platziert werden.
Die Breite wird mit einem Prozentwert angegeben und muss bei einer eventuellen Änderung der Containerbreite nicht mehr angepasst werden.
box-sizing: border-box
lassen sich viele Schwierigkeiten beim Layouten umgehen. Dies gilt vor allem dann, wenn prozentuale Angaben für Abmessungen mit anderen Längenangaben kombiniert werden sollen.Lösung 2: Der mathematische Weg
Mit der calc()-Funktion können Sie eine mathematische Berechnung als Wert verwenden:
section, aside {
width: calc(33.3% - (2px + 10px + 10px));
height: calc(200px - (2px + 10px ));
border: 1px solid red;
margin: 0 5px;
padding: 5px;
float: left;
}
.spalte
erhalten nun die Berechnung aus der Breite von einem Drittel als Prozentangabe und der Summe der Ränder: calc(33.3% - (2px + 10px + 10px))
height
berechnet sich aus der absoluten Höhe, von der die Randstärke und der Innenabstand (der margin oben und unten beträgt 0) abgezogen werden.- Bei jeder Änderung der Werte für Abstände und Randlinien müssen Sie die Formel anpassen!
- Die Browser rechnen intern mit Integer-Werten anstatt „echten“ Pixeln (, die es im Gewirr zwischen physikalischen und logischen Pixeln gar nicht gibt). Deshalb kann es zu geringfügigen Rundungsfehlern kommen.
- Die float-Eigenschaft ist dafür gedacht, Bilder oder andere Elemente innerhalb eines Textes umfließen zu lassen. Für mehrspaltige Layouts ist eine Umsetzung mit Flexbox oder dem Grid Layout Stand der Technik.
- Die einzelnen Spalten haben eine feste Höhe. Wenn Sie, wie im zweiten section-Element, mehr Inhalt haben, ragt dieser über die Grenzen des Elements hinaus. („zerschossenes Layout“).
Die hier vorgestellte Positionierung mit float ist heute verpönt, da sie viele Nachteile aufweist. Pixelgenaue Layouts sind immer nur für eine Auflösung optimiert und führen bei anderen Viewportgrößen zu Rändern oder einem „zerschossenen“ Layout.
Stand der Technik ist eine Umsetzung mit Flexbox oder dem Grid Layout:
Lösung 3: flexibles Layout
Flexbox ist eine sehr moderne und einfache Möglichkeit, responsive und flexible Layouts zu erstellen, ohne feste Größenangaben und weitere CSS-Einstellungen wie position, float oder clear nutzen zu müssen. Dabei kann nicht nur die Größendarstellung, sondern auch die Reihenfolge der Elemente unabhängig vom HTML-Code durch CSS festgelegt werden.
article {
border: 1px solid;
display: flex;
}
section, aside {
border: 1px solid red;
padding: 5px;
flex: 1;
}
- Das article-Element wird durch display: flex zum flexiblen Container.
- Die einzelnen section-Elemente verteilen sich, da die Flex-basis mit flex: 1 gleich ist, gleichmäßig auf den verfügbaren Raum.
- Es passt sich flexibel an den vorhandenen Platz an.
- Bei einer Änderung des Markups sind keine oder nur wenig Änderungen am CSS nötig.
Lösung 4: flexibel mit Grid Layout
Mit dem Grid Layout Module ist es möglich, responsive zweidimensionale Layouts zu erstellen. Dabei wird ein Raster angelegt, in dem sich die Kindelemente ohne feste Größenangaben und weitere CSS-Einstellungen wie position, float oder clear bequem und flexibel positionieren (lassen).
article {
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1em;
}
section, aside {
border: 1px solid red;
padding: 5px;
}
- Das article-Element wird durch display: grid zum Grid-Container.
-
grid-template-columns: 1fr 1fr 1fr;
legt drei gleichbreite Spalten an -
grid-gap: 1em;
lässt zwischen den Spalten (aber nicht am Außenrand) einen 1em breiten Rand - Die section-Elemente benötigen keine eigene Festlegungen!
- Es passt sich flexibel an den vorhandenen Platz an.
- Bei einer Änderung des Markups sind keine oder nur wenig Änderungen am CSS nötig.
Fazit
- Verzichten Sie auf den Versuch ein pixelgenaues Layout erzeugen zu wollen.
- Verzichten Sie auf Höhenangaben. Wenn der Inhalt größer wird, setzt er sich automatisch nach unten fort.
- Verzichten Sie auf feste Breitenangaben. Verwenden Sie Eigenschaften wie min-width, um sicherzustellen, dass das Element breit genug für den Inhalt ist.
- Verwenden Sie moderne, responsive Layout-Modelle wie Flexbox oder Grid Layout. Sie sind für alle Viewports geeignet und passen sich flexibel an den verfügbaren Platz an.
Im visuellen Anzeigemodell erfolgt die Darstellung von Elementen durch das Zeichnen von Rechtecken. Die Bestandteile dieser Rechtecke beschreibt das „Boxmodell“. Eine Box kann bestehen aus:
- Dem Inhaltsbereich (client area), also der Fläche, die durch Texte und Bilder oder Eigenschaften wie width und height vorgegeben wird,
- einem Innenabstand (padding),
- einem Rahmen (border) und
- einem Außenabstand (margin).
Bei Block-Elementen können Höhe und Breite beliebig festgelegt werden, bei Inlineelementen werden die Maße durch den Inhalt vorgegeben.
Innen- und Außenabstände sowie Rahmen können für jede der vier Seiten einer Box einzeln festgelegt werden.
Wird eine Box positioniert, beginnt die linke Außenkante bei left
, die obere Außenkante bei top
, die rechte Außenkante bei right
und die untere Außenkante bei bottom
. Da dies nur bei einer Schreibrichtung von links nach rechts wirklich stimmig ist, wurden die logischen Eigenschaften eingeführt, die im letzten Kapitel dieses Kurses vorgestellt werden.
Referenz-Box
Die einzelnen Rechtecke werden von innen nach außen bezeichnet als
-
content-box
: (Inhaltsbox) Bereich, der durch den Inhalt oder die Eigenschaftenwidth
undheight
festgelegt wurde. -
padding-box
: (Polsterungsbox) Bereich, dercontent-box
und padding (Innenabstand) umfasst. Besitzt eine Seite keinen Innenabstand, so ist die Polsterungskante mit der Innenkante identisch. -
border-box
: (Rahmenbox) Box, diecontent-box
, einen möglichen Innenabstand und die durch border festgelegten Rahmen umfasst. Besitzt eine Box keinen Rahmen, so ist die Rahmenbox mit der Polsterungsbox identisch. -
margin-box
: Box mitsamt durch margin festgelegten Außenabständen. Sind für eine Box keine Außenabstände definiert, so ist die Außenkante mit der Rahmenkante identisch.
Information: Geschichtliches
Die ursprüngliche Definition, die Angaben von width
und height
als Abmessungen lediglich des Inhaltes festzulegen ist wenig intuitiv. Eigentlich erwartet man, dass eine Breiten- bzw. Höhenangabe den gesamten Platzbedarf des Elementes widerspiegelt.
Zudem interpretierten alte Internetexplorer das Box-Modell falsch, sodass Webentwickler auf diese besondere Rücksicht nehmen mussten (Quirks Mode). Ebenso war es schwierig bis unmöglich, ein responsives Layout zu erstellen, welches etwa prozentuale Breitenangaben mit pixelgenauen Angaben für die Rahmenbreite kombinierte.
Diese Bezeichnungen finden sich als Werte in einigen Eigenschaften wieder, etwa box-sizing, background-clip, background-origin oder mask.
Was bei pixelgenauem Layout zu Rundungsfehlern, dem Zwang zu Browserweichen und zusätzlichem Wartungsaufwand führte, erwies sich im flexiblen Layout als nahezu unmöglich:
I would love a different box model! I find it bizarre that padding and border add the width of an object, and would love to be able to give something like a textarea 100% width and 3px padding without worrying what it’s going to do the layout. Perhaps something like padding-inside as a new selector?In that vein I also wish I could specify a 100% width for an element, minus a set fixed width. Again, very useful when creating fluid designs with form elements!
Jon Hicks: CSS Wishlist: 21 Designer/Developers Sound Off[1]
Alternatives Box-Modell mit box-sizing
Mit der box-sizing-Eigenschaft können Sie bestimmen, worauf sich Angaben zu den Abmessungen eines Elementes beziehen. Damit können Sie zwischen dem klassischen Boxmodell und dem intuitiveren des Quirksmodus umschalten.
Erlaubt sind dabei eine der folgenden Angaben.
-
content-box
, Standardwert, Angabe gilt nur für den Inhalt -
border-box
, Angabe gilt für Inhalt, Innenabstand und Rahmen. Dies entspricht dem Quirksmodus des Internet Explorers.
section {
border: 1em solid green;
padding: 1em;
width: 20em;
}
#content-box {
box-sizing: content-box;
}
#border-box {
box-sizing: border-box;
}
<section id="content-box">
...
</section>
<section id="border-box">
...
</section>
section
-Elemente die jeweils einen Rahmen und einen Innenabstand der Breite 1em haben. Ebenso haben beide eine Breite von 20em zugewiesen bekommen.Beim ersten
section
-Element wird eine Inhaltsbreite von 20em festgelegt, beim zweiten Element ergeben sich die 20em als Summe der Breiten von Inhalt, Innenabstand und Rahmen.Praktischer Einsatz
box-sizing
innerhalb eines Dokuments verzichten.Die Eigenschaft box-sizing
wird nicht automatisch vererbt. Deshalb schlug Chris Coyier vor, für die box-sizing Eigenschaft global den Wert inherit
festzulegen.[2]
Miriam Suzanne widerspach diesem Ansatz auf der 2018er beyond tellerand Konferenz und empfahl, auf die Vererbung zu verzichten und einfach bei allen Elementen den Wert für box-sizing festzulegen:
There’s a reason that box model doesn’t inherit by default, and there’s no reason that it should inherit. We don’t inherit margins, we don’t inherit borders. Layouts should not be inherited; layouts don’t nest in that way. So I don’t recommend this solution.Es gibt einen Grund, weshalb das Boxmodell nicht per Default vererbt wird, und es gibt keinen Grund, dass es vererbt werden sollte. Wir erben keine Margins, wir erben keine Borders. Layouts sollten nicht vererbt werden, Layouts schachteln sich nicht auf diese Art. Also, diese Lösung empfehle ich nicht.
Miriam Suzanne: Don’t use my grid system or any others (ab 8:15)[3]
box-sizing
wird für alle Elemente auf border-box gestellt.Siehe auch
- Box-Model-Bug und Quirks Mode
Weblinks
- Codepen/carolineartz interaktive Demo der verschiedenen Möglichkeiten
Quellen
- ↑ Jon Hicks:CSS Wishlist: 21 Designer/Developers Sound Off
- ↑ Inheriting box-sizing Probably Slightly Better Best-Practice By Chris Coyier On July 15, 2014
Vererbung von box-sizinghtml { box-sizing: border-box; } *, ::before, ::after { box-sizing: inherit; }Die Eigenschaft
box-sizing
wird nur für html eingestellt und alle Elemente erben den Wert ihres Elternelements. Hierdurch wird eine Änderung bei einem Element auf dessen Kindelemente weitervererbt. Bei*, ::before, ::after {box-sizing: border-box;}
würden die Kindelemente einen anderen Ausgangswert nicht übernehmen. - ↑ Miriam Suzanne:Don’t use my grid system or any others (ab 8:15)
Als Spalten dienen drei section-Elemente, die eine feste Breite und Höhe von je 200px (ein Drittel von 600px) besitzen.
Damit die Divs nebeneinander platziert werden, erhalten sie ein
display: inline-block;
.