CSS/Tutorials/Einstieg/Box-Modell
Mit CSS können Sie Elementen (feste) Breiten, Höhen und Abstände geben und diese nebeneinander positionieren. 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.
Inhaltsverzeichnis
das Box-Modell[Bearbeiten]
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.
In den vorherigen Kapiteln 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;
}
p {
width: 200px;
color: green;
background-color: lightyellow;
border: 2px solid red;
border-radius: 0 1em 1em 1em;
margin: 20px auto;
padding: 2em;
}
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?[Bearbeiten]
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[Bearbeiten]
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;
}
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;
.
- Betrachten Sie das Beispiel im Frickl als auch in einem neuen Tab. Was beobachten Sie?
- Verändern Sie im Frickl die Werte für Breite, Höhe, Randlinien und Abstände. Was beobachten Sie?
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[Bearbeiten]
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.
modernes WebDesign[Bearbeiten]
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: Der mathematische Weg[Bearbeiten]
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“).
Hinweis
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 2: Das alternative Boxmodell[Bearbeiten]
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;
}
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.
Hinweis
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 3: flexibles Layout[Bearbeiten]
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.
Dieses Layout hat mehrere Vorteile:
- 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[Bearbeiten]
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!
Dieses Layout hat mehrere Vorteile:
- Es passt sich flexibel an den vorhandenen Platz an.
- Bei einer Änderung des Markups sind keine oder nur wenig Änderungen am CSS nötig.
Mehr über das bereits von allen Browsern unterstützte Grid layout erfahren Sie im nächsten Kapitel!
Fazit[Bearbeiten]
- 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.
Einen Nachteil hat unser Beispiel noch: Im Frickl und auf mobilen Geräten mit kleinen Viewports sind die drei Spalten sehr schmal. Wie Sie einstellen, dass die Spalten nur bei ausreichender Breite angezeigt werden, erfahren Sie im nächsten Kapitel!
Exkurs: Gestaltungstipps[Bearbeiten]
CSS-basierte Layouts und die Möglichkeiten der neuen CSS3-Eigenschaften können dazu verleiten, jede Box mit einem durchgehenden, gestrichelten oder gar gepunkteten Rahmen abzugrenzen. Dies ist bei den hier aufgeführten Beispielen nur zu Demonstrationszwecken der Fall.
- Seien Sie kreativ und nutzen Sie die CSS-Eigenschaft
border
für Rahmen sinnvoll und sparsam. - Wenn Sie Bereiche mit Rahmen, Schatten, einfachen Linien oder über eine Hintergrundfarbe abgrenzen, setzen Sie für den enthaltenen Text auch einen passenden Innenabstand.
Bringen Sie Farbe in Ihre Seiten – aber übertreiben Sie es nicht.
- Wählen Sie zueinander passende, ähnliche Farbtöne. Darüber hinaus können Sie Akzente in Komplementärfarben setzen. Achten Sie aber bitte auf einen ausreichenden Farb- und Helligkeitskontrast, damit Ihre Texte auch ohne Anstrengung gelesen werden können. Hierzu eignet sich dunkle Schrift vor hellem Hintergrund am besten.
- contrast checker (englisch)
- wcag contrast checker (Firefox-Addon)
- Setzen Sie bitte auch nicht voraus, dass in jedem Browser Schwarz als Schriftfarbe und Weiß als Hintergrundfarbe voreingestellt ist. Wenn Sie den Hintergrund definieren, vergessen Sie auf keinen Fall, die Vordergrundfarben und Schriftfarben anzugeben, da Sie hier nicht immer mit einheitlichen Voreinstellungen rechnen können.
- Es ist für Ihre Besucher hilfreich, wenn besuchte Links von unbesuchten farblich zu unterscheiden sind.
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 mitmargin: 20px auto;
einen Abstand von 20px nach oben (und unten), sowie mitauto
einen gleichmäßig verteilten Abstand nach rechts und links. In Verbindung mit der Festlegung für die Breitewidth: 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)