Abgabebeispiel

Erweitertes CSS: Fonts, Flexbox und Raster

Als Designerinnen und Designer lieben wir unsere Fonts und Raster – aber wie bekommen wir diese auf unsere Websites?

Wiederholung

Beim letzten Mal haben wir die Grundlagen von CSS kennengelernt. Ihr wisst jetzt, wie man ein CSS-Stylesheet erstellt, was Selektoren sind und wie Regeln funktionieren. Außerdem habt ihr gesehen, wie Spezifität und Vererbung den Aufbau eurer Stylesheets beeinflussen.

Warum sollte man statt Inline-Styling ein Stylesheet verwenden?

Weil Inline-Styles nicht tragbar sind. Sie müssen für jedes Element einzeln definiert werden und vermischen Darstellung (CSS) zu sehr mit Struktur (HTML). Stylesheets sind wiederverwertbar und sauber abgetrennt.

Wie bettet man ein Stylesheet in ein HTML-Dokument ein?

Da ein Stylesheet eine externe Datei ist, muss sie in jedes HTML-Dokument eurer Website eingebettet werden. Das macht ihr, indem ihr im <head>-Element folgendes Tag einfügt: <link rel="stylesheet" href="/pfad/zum/stylesheet.css"> – dadurch werden alle zutreffenden Regeln aus diesem Stylesheet auf das HTML-Dokument angewandt.

Was sind die drei häufigsten Selektoren?

Die häufigsten Selektoren in Stylesheets sind:

  1. Element-Selektoren: einfach der Name des HTML-Elements, z.B. h1

  2. Klassen-Selektoren: der Wert eines class-Attributs mit einem Punkt davor, z.B. .fancy

  3. ID-Selektoren: der Wert eines id-Attributs mit einem Hashtag davor, z.B. #content

Mehrere Elemente können dabei die gleiche Klasse haben, ein Element kann mehrere Klassen haben, aber nur ein einziges Element darf eine bestimmte ID besitzen.

Was ist die Aufgabe der var()-Funktion?

Mit der var()-Funktion könnt ihr zuvor definierte Variablen als Werte in CSS-Eigenschaften einsetzen. Variablen definiert ihr, indem ihr im :root-Selektor (oder anderen Regeln) den Namen eurer Variable mit zwei Bindestrichen (-) eintragt und einen beliebigen Wert zuweist, z.B. --text-color: black. Habt ihr das getan, könnt ihr die Variable innerhalb einer anderen Regel mit color: var(--text-color); verwenden.

Was hat es mit der Spezifität auf sich?

Spezifischere Regeln überschreiben weniger spezifische. Die Spezifität einer Regel hängt von ihrem Selektor ab. Ein Element-Selektor ist zum Beispiel weniger spezifisch als ein Klassen-Selektor.

Selektoren können aber auch mit verschiedenen Kombinatoren spezifischer gemacht werden. Als Grundsatz gilt: Je länger ein Selektor, desto spezifischer ist er wahrscheinlich auch.

Wie funktioniert Vererbung in CSS?

Die CSS-Eigenschaften werden von Elternelementen an ihre Kindelemente vererbt. D.h. eine Eigenschaft, die auf einem Element gesetzt wird, gilt normalerweise auch für alle Elemente, die innerhalb dieses Elements verschachtelt sind. So könnt ihr beispielsweise die Textfarbe für euer ganzes Dokument einfach in einem body-Selektor festlegen und alle anderen Elemente innerhalb des <body>-Elements, die keine eigene Textfarbe definieren, werden in dieser Farbe angezeigt.

Ihr könnt ein Element auch explizit anweisen, eine Eigenschaft zu erben, indem ihr den Wert dieser Eigenschaft für das Element auf inherit setzt.


Eigenschaften in CSS

In CSS steuert ihr die Darstellung von Elementen über sogenannte „Eigenschaften“. Jede dieser Eigenschaften hat einen bestimmten Typ, der vorgibt, welche Werte für diese Eigenschaft verwendet werden können. Mehr dazu könnt ihr hier im MDN nachlesen. Beispiele für verschiedene Typen sind Längen, Winkel, Farben und Schlüsselwörter. Viele Werte haben außerdem bestimmte Einheiten. Dabei unterscheidet man vor allem zwischen relativen und absoluten Einheiten.

Absolute Einheiten

Eine absolute Einheit ist ein fixer Wert. Zum Beispiel entspricht die Einheit „px“ immer einer fixen Anzahl an Pixeln auf dem Bildschirm und die Einheit „deg“ immer einer fixen Anzahl an Grad (in einem Winkel).

Relative Einheiten

Im responsiven Web ist aber sehr viel nicht absolut. Denn auch wenn ein Bildschirm eine fixe Auflösung hat, kann ein Fenster auf diesem Bildschirm sehr viele verschiedene Größen annehmen. Außerdem stellen Menschen mit Sehschwäche vielleicht die Grundschriftgröße ihres Browsers höher, um nicht so viel zoomen zu müssen – und überhaupt ist es eigentlich in den meisten Fällen besser, den Browser die Layoutarbeit übernehmen zu lassen. Absolute Werte stehen dem oft im Weg.

Deshalb gibt es die relativen Einheiten. Die wohl bekannteste unter ihnen ist sicherlich „%“ – wenn man in CSS z.B. eine Länge in Prozent angibt, bezieht diese sich auf einen Bruchteil der Breite oder Höhe eines Elements. 50% sind nicht gleich 50%, die effektive Länge hängt von einem anderen Wert ab. Deshalb ist es eine relative Einheit.

Weitere relative Einheiten sind:

  • vw / vh: 1% der Breite bzw. Höhe des nutzbaren Bereichs des Browserfensters

  • em: relativ zur Schriftgröße des Elternelements, z.B. sind 1em 16px, wenn die Schriftgröße des Elternelements 16px ist, 1.5em wären dann 24px

  • rem: wie em, aber immer bezogen auf die Schriftgröße des <html>-Elements und somit der Einstellungen des Nutzers, falls ihr sie nicht explizit setzt – die beste Einheit für fixe Größen!

Häufige CSS-Eigenschaften

Es gibt in CSS unfassbar viele Eigenschaften, sie alle auswendig zu wissen, ist absolut nicht nötig. Falls ihr neugierig seid, könnt ihr den CSS-Tricks Almanac durchstöbern, um herauszufinden, welche verrückten Eigenschaften es gibt.

Trotzdem gibt es Eigenschaften, die man eigentlich auf fast jeder Website benötigt und die sich somit irgendwann im Gehirn einnisten. Hier sind die Häufigsten:

  • color: bestimmt die Schriftfarbe

  • background-color: die Hintergrundfarbe

  • background-image: das Hintergrundbild, wird auch für Verläufe verwendet, da Verläufe in CSS als Bilder zählen

  • font-family: die Schriftart

  • font-size: die Schriftgröße

  • font-weight: den Schriftschnitt

  • line-height: den Zeilenabstand

  • text-align: die Textausrichtung, also linksbündig, rechtsbündig, zentriert, im Blocksatz

  • opacity: die Deckkraft

  • border: den Rahmen um ein Element

  • border-radius: den Grad der Rundung der Ecken eines Elements

  • box-shadow: den Schlagschatten

  • margin: Abstand zu anderen Elementen außerhalb des Elements

  • padding: Abstand von Kindelementen zum Rand des Eltern-Elements

  • width/height: Breite / Höhe eines Elements – passt vor allem mit width auf, das kann unschöne Nebeneffekte haben!

  • display: Anzeigeform eines Elements, also ob es sich wie ein Inline- oder Block-Element verhalten soll. Hiermit kann man auch mächtige Layoutwerkzeuge wie flex und grid aktivieren – mehr dazu später.

<h1>Hallo Welt!</h1>
body {
color: black; /* Farbe */
max-width: 640px; /* absolute Länge */
margin: 0 auto; /* Zahl, Schlüsselwort */
}
h1 {
color: #444; /* Farbe */
font-size: 2rem; /* relative Länge */
text-decoration: underline; /* Schlüsselwort */
width: 50%; /* relative Länge (320px) */
text-align: center; /* Schlüsselwort */
border: 0.0625rem solid magenta; /* relative Länge (1px), Schlüsselwort, Farbe */
}

Typografie auf Websites

Wir Designerinnen und Designer lieben unsere Schriftarten – sicherlich habt ihr euch auch schon Gedanken darüber gemacht, welche Schriften ihr gerne auf eurer Website verwenden möchtet und in welchem Verhältnis die Schriftgrößen zueinander stehen sollen.

Die Grundschriftart eurer Website könnt ihr mit der font-family-Eigenschaft direkt im body-Selektor setzen. Falls ihr dann für Überschriften oder andere spezielle Elemente eine andere Schriftart verwenden möchtet, könnt ihr diese dann bei Bedarf mit spezifischeren Selektoren überschreiben.

Der Wert von font-family ist eine mit Kommas getrennte Liste von Schriftarten, die der Browser von links nach rechts durchgeht, bis er eine der gelisteten Schriften laden kann, z.B. font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif; – der Browser kann nur Schriften laden, die entweder bereits auf dem Gerät des Nutzenden installiert sind, oder die die Website mitliefert.

Achtet beim Definieren von font-family also unbedingt darauf, immer einen Standardwert (sans-serif oder serif) ans Ende der Liste zu packen, damit euer Text auch dann angezeigt wird, falls keine der vorher gelisteten Schriften geladen werden kann!

Weitere wichtige Eigenschaften für die Gestaltung eures Schriftbilds sind (zusätzlich zu den zuvor genannten häufigen Eigenschaften):

  • font-style: entweder normal (Standard) oder italic, also kursiv

  • letter-spacing: der Abstand zwischen Buchstaben

  • text-transform: Buchstabentransformation, kann mit uppercase für Versalien verwendet werden

<h1>Hallo Welt!</h1>
<p>
Ich bin nur ein kleiner <strong>Einleitungstext</strong>,
der ein paar <em>Kleinigkeiten</em> verdeutlicht.
</p>
body {
/* font-family wird an alle Kinder vererbt */
font-family: 'Futura', 'Arial', sans-serif;
font-size: 1rem; /* entspricht norm. 16px */
line-height: 1.4; /* zw. 1.4 & 1.5 */
}
h1 {
text-transform: uppercase; /* Versalien */
letter-spacing: 4px; /* Buchstabenabstand */
font-weight: 900; /* Fettester Schnitt */
font-size: 2rem; /* 2*1rem = 32px */
}
em {
font-style: italic; /* kursiv */
}
strong {
font-weight: bold; /* geht auch, ca. 700 */
}

Fonts in CSS

Wie angemerkt, können auf eurer Website nur Schriften angezeigt werden, die bereits installiert sind, oder von eurer Website mitgeliefert werden. Um eine Schrift „mitzuliefern“, benötigt ihr die Lizenzrechte, das zu machen. Oft müssen diese Lizenzen separat gekauft werden und das kann teuer und kompliziert werden, weil man nach Website-Besuchern abgerechnet wird. Deshalb ist es gerade für den Anfang sinnvoller, freie Schriften z.B. von Fontsource zu verwenden.

Wenn ihr eine Schrift mitliefert, solltet ihr darauf achten, nur die Schnitte und Zeichensätze zu laden, die ihr auch für die Anzeige auf eurer Website braucht. Wenn ihr keine kyrillischen Texte auf eurer Website habt, dann braucht ihr auch nicht das gesamte kyrillische Alphabet zu laden.

Bitte vermeidet es auch tunlichst Schriften, direkt von externen Seiten wie Google Fonts oder Adobe Fonts einzubetten. Das stellt in den meisten Fällen ein Datenschutzproblem dar und kann sogar zu Performanceproblemen führen. Stellt also bitte sicher, dass ihr die Schriftdateien wirklich zusammen mit eurer Website ausliefert.

Eine Schrift von Fontsource einbetten

Zum Glück gibt es die meisten Google Fonts auch auf Fontsource. Somit könnt ihr sie euch also von dort herunterladen und direkt in eure Website einbetten. Dazu geht ihr folgendermaßen vor:

Schritt 1: Schrift auswählen

Geht auf fontsource.org und sucht euch die Schrift aus, die ihr verwenden möchtet. In diesem Beispiel verwende ich „Atkinson Hyperlegible Next“.

Randbemerkung: Es gibt inzwischen sogenannte „Variable“ Fonts. Diese bündeln mehrere Schnitte (und weitere Funktionen) in verschiedene „Achsen“, die man frei verstellen kann. Falls es für eure gewählte Schrift also eine variable Version gibt, verwendet ruhig die. Variable Fonts sind flexibler und moderner als traditionelle.

Schritt 2: Zeichensätze konfigurieren

Klickt auf den Button „CDN“ rechts oben auf der Schrift-Detailseite. Dadurch gelangt ihr zu einem Konfigurator, in dem ihr für eure Schrift verschiedene Schnitte (im Falle eines nicht-variablen Fonts) und Zeichensätze konfigurieren könnt. In den meisten Fällen benötigt ihr nur den „latin“-Zeichensatz und die Schnitte 400 und 700 bzw. die „wght“-Achse bei variablen Fonts. Den „Display“-Wert könnt ihr auf „swap“ lassen, er steuert, wie die Schrift angezeigt wird, bevor sie geladen hat.

Für nicht-variable Fonts gibt es leicht andere Optionen

Schritt 3: CSS Kopieren

Der Konfigurator gibt euch am Ende ein CSS-Snippet, mit dem ihr die Schrift in eure Website einbetten könnt. Kopiert euch den Code und legt in eurem Website-Ordner unter „assets“ eine neue Datei „fonts.css“ an. Dort fügt ihr den Code dann ein.

Theoretisch könntet ihr den Code auch in eure Haupt-CSS-Datei einfügen, aber ich denke, es ist sauberer, die Schriften in ihrer eigenen Datei zu haben, da es gerade mit vielen Schnitten schnell unübersichtlich werden kann.

/* atkinson-hyperlegible-next-latin-wght-normal */
@font-face {
font-family: 'Atkinson Hyperlegible Next Variable';
font-style: normal;
font-display: swap;
font-weight: 200 800;
src: url(https://cdn.jsdelivr.net/fontsource/fonts/atkinson-hyperlegible-next:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

Schritt 4: Schriftdateien herunterladen und Quelle austauschen

Zu guter Letzt müsst ihr die Links in den url()-Werten im Browser öffnen, um so die eigentliche Schriftdatei herunterzuladen. Speichert sie am besten in einem Unterordner „fonts“ im selben Ordner wie eure „fonts.css“-Datei.

Habt ihr alle Schriftdateien heruntergeladen, müsst ihr die url()-Werte auf den lokalen Pfad zur richtigen Schriftdatei ändern, damit euer CSS-Code keine Anfragen an fremde URLs schickt.

@font-face {
/* ... anderer Code ... */
src: url(./fonts/latin-wght-normal.woff2) format('woff2-variations');
/* ... anderer Code ... */
}

Habt ihr das getan, solltet ihr die „fonts.css“-Datei vor euren anderen CSS-Dateien in eurem HTML-Code verlinken. Dadurch könnt ihr dann in eurer Haupt-CSS-Datei die neue Schriftart mit dem Namen aus der „fonts.css“-Datei verwenden:

body {
/* ... anderer Code ... */
font-family: 'Atkinson Hyperlegible Next Variable';
font-weight: 400;
/* ... anderer Code ... */
}

Farben

Die gute Nachricht zuerst: Im Gegensatz zu Schriften, kommen (fast) alle Farben direkt vorinstalliert in eurem Browser. 😉 Somit steht farbenfrohen Websites nichts im Weg.

Ihr könnt Farben in CSS als benannte Farben, Hex-Codes, RGB-Funktionen und in vielen weiteren Formen angeben. Anfangs werdet ihr in den meisten Fällen mit Hex-Codes, z.B. #ffffff, für Farben ohne Transparenz und der RGB-Funktion, z.B. rgb(255, 255, 255 / 0.5) für Farben mit Transparenz arbeiten. Beide Formen könnt ihr aus eurem Design-Tool der Wahl auslesen, bei RGB-Funktionen müsst ihr nur beachten, dass man in CSS die Deckkraft der Farbe immer nach einem Slash (/) mit einem Wert von 0 (transparent) bis 1 (volle Deckkraft) angibt.

Falls ihr eine Farbe als Variable angelegt habt, könnt ihr auch schnell die Deckkraft verwenden, indem ihr rgb(from var(--name-der-variable) r g b / 0.5 verwendet. Mit der color-mix()-Funktion könnt ihr außerdem mehrere Farben miteinander mischen, aber die genaue Syntax geht über den Rahmen dieses Kurses hinaus – schaut sie gerne nach, falls sie euch interessiert.

Wie bereits angemerkt, könnt ihr die Textfarbe für ein Element mit der Eigenschaft color und die Hintergrundfarbe mit der Eigenschaft background-color. Für Farbverläufe müsst ihr hingegen background-image verwenden, da in CSS Verläufe als Bilder zählen.

Es gibt verschiedene Funktionen für Verläufe, die einfachste ist linear-gradient() für einen linearen Farbverlauf, aber es gibt auch radial-gradient() und conic-gradient() für radiale und konische Verläufe. In Figma (und anderen Tools) könnt ihr euch den genauen Code für einen Verlauf meistens mit Rechtsklick -> Copy / Paste as -> Copy as code -> CSS kopieren.

<div class="fancy">
Hier ist ein bisschen text.
</div>
<p>Hallo, ich bin mehr Text mit einem <a href="#">link</a>.</p>
<ul>
<li class="swatch"></li>
<li class="swatch"></li>
<li class="swatch"></li>
</ul>
div.fancy {
padding: 1.5rem;
color: white; /* fester Wert */
background-color: #444; /* hex-Code */
background-image:
linear-gradient(45deg, #0093E9, #80D0C7);
/* Besteht aus: Winkel, Farbe, Farbe */
}
p {
color: #222222; /* hex-Code */
}
a {
color: rgb(120 79 237 / 0.5); /* rgb-Funktion */
}
ul {
padding: 0;
list-style: none;
display: flex;
gap: 1.5rem;
li {
width: 4rem;
height: 4rem;
&:first-child {
background-image: linear-gradient(45deg, #0093E9, #80D0C7);
}
&:nth-child(2) {
background-image: radial-gradient(circle at 25% 25%, #0093E9, #80D0C7);
}
&:last-child {
background-image: conic-gradient(from 45deg, #0093E9, #80D0C7);
}
}
}

Natürlich kann man mit background-image auch richtige Bilder als Hintergrundbilder eines Elements setzen – allerdings kann man für diese aktuell noch keinen Alt-Text hinterlegen. Das kann für die Barrierefreiheit schädlich sein. Stattdessen sollte man also ein <img>-Element verwenden und dieses mit CSS so positionieren, dass es hinter den anderen Inhalten eines Elements liegt.

Das Box-Modell

Wie wir gegen Anfang des Kurses schon festgestellt haben, sind HTML-Elemente immer rechteckige Boxen. Deshalb spricht man auch vom „Box-Modell“. Denn Plottwist: Jedes HTML-Element besteht sogar aus vier kleineren Boxen!

Jedes HTML-Element hat:

  • Eine Margin-Box, also den Abstand vom Rand des Elements zu anderen Elementen

  • Eine Border-Box, die Box, die einen etwaigen Rahmen des Elements beinhaltet

  • Eine Padding-Box, also den Abstand von Kindelementen zum Rand des Elements

  • Eine Content-Box, die eigentliche Box des Elements, in der der Inhalt lebt

Wenn ihr in CSS mit width und height Breite und Höhe eines Elements festsetzt, bezieht sich das standardmäßig auf die Content-Box. Falls ihr also einen Rahmen und / oder ein Padding verwendet, fällt die tatsächliche Box unter Umständen größer aus als eure Angabe.

Wenn ihr beispielsweise width: 100px; und padding: 20px setzt, ist das Element auf der Seite letztlich 140 Pixel breit, denn zu den 100 Pixeln der Content-Box kommen links und rechts noch jeweils 20 Pixel Padding (100 + 20 + 20 = 140).

Um das intuitiver zu machen, könnt ihr mit der Eigenschaft box-sizing kontrollieren, wie die gesamte Breite und Höhe eines Elements berechnet wird. Ich verwende dafür gerne den Wert border-box, damit sich Angaben zur Breite und Höhe auf die Border-Box eines Elements beziehen. Mit box-sizing: border-box; wäre die Breite des Elements in unserem Beispiel tatsächlich 100 Pixel, so wie wir es erwarten würden.

<div class="margin">
<div class="box"></div>
</div>
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-content: center;
.margin {
background-color: rgb(from #FF9900 r g b / 0.5);
.box {
width: 8rem;
height: 8rem;
padding: 1.5rem;
margin: 1.5rem;
background-clip: content-box, padding-box;
background-image: linear-gradient(#9FEEFF), linear-gradient(#C0FFAA);
border: 1.5rem solid #FFE600;
}
}
}

Margin und Padding

Wie bereits angemerkt, sind margin und padding wichtige Eigenschaften, mit denen ihr kontrollieren könnt, wie die Abstände von Elementen zueinander sind. Mit margin gebt ihr an, wie viel Abstand zwischen verschiedenen Elementen sein soll, z.B. zwischen mehreren Bildern, oder auch zwischen einer Überschrift und dem Fließtext danach. Margins können auch negativ sein, das erlaubt es euch beispielsweise, Elemente zu überlappen – aber passt auf, negative Margins können schnell zu Verwirrung führen!

Mit padding legt ihr hingegen fest, wie viel Abstand Kindelemente zum Rand des Eltern-Elements haben sollen, also z.B. wie viel Weißraum zwischen eurem Logo und dem Rand eures <header>-Elements bestehen soll.

Margin-Collapse

Es gibt beim Margin eine kleine Besonderheit: Die Abstände ober- und unterhalb mehrerer Elemente können zusammengefasst („kollabiert“) werden. Dabei überschreibt der größere der beiden Werte dann den kleineren. Habt ihr z.B. eine <h1> mit margin-bottom: 32px; gefolgt von einem <p>-Element mit margin-top: 16px, dann wird der Abstand zwischen beiden Elementen 32 Pixel sein, da die Margins zusammengefasst werden und die 32 Pixel die 16 Pixel überschreiben.

Dies ist allerdings nur in bestimmten Fällen gegeben, z.B. wenn Elemente Geschwister sind, d.h. sich im selben Eltern-Element befinden. Die genauen Regeln und ihre Ausnahmen werden schnell kompliziert und ich werde an dieser Stelle nicht näher darauf eingehen. Falls ihr euch aber einmal fragen solltet, weshalb ein Abstand zwischen Elementen kleiner ist als erwartet, liegt das sehr wahrscheinlich an dem Margin-Collapse.

Shorthand-Eigenschaften

Euch ist vielleicht aufgefallen, dass ich in den vorhergehenden Beispielen teilweise von margin-top und margin-bottom gesprochen habe, aber teilweise auch einfach nur von margin. Das liegt daran, dass bestimmte Eigenschaften wie padding, border und eben margin sogenannte „Shorthand“-Eigenschaften sind, mit denen sich mehrere Eigenschaften auf einmal setzen lassen. Das ist gerade dann besonders nützlich, wenn man z.B. denselben Abstand an allen Seiten eines Elements setzen möchte.

padding: 24px; ist daher gleichbedeutend mit padding-top: 24px; padding-left: 24px; padding-right: 24px; padding-bottom: 24px;.

Man kann einer Shorthand aber teilweise auch mehrere Werte geben. Diese gelten dann wie folgt:

  • 2 Werte: Oben und unten, links und rechts, z.B. padding: 12px 24px;

  • 3 Werte: Oben, links und rechts, unten, z.B. margin: 12px auto 24px;

  • 4 Werte: Oben, rechts, unten, links, z.B: padding: 12px auto 24px auto;

Welche Shorthand wie eingesetzt werden kann und wie sie sich bei verschiedenen Werten verhält, schaut ihr euch am besten auf DevDocs oder im CSS-Tricks Almanac an.

<section>
<div class="inner"></div>
</section>
body {
/*
mit max-width kann eine maximale Breite
angegeben werden, in Kombination mit dem
unten definierten Margin wird der Content
so auf der Seite zentriert
*/
max-width: 640px;
/* 0px oben + unten, auto links + rechts */
margin: 0 auto;
padding: 96px 16px 128px 32px;
/* Bedeutet das Gleiche wie: */
/* padding-top: 96px;
padding-right: 16px;
padding-bottom: 128px;
padding-left: 32px; */
}
section {
padding: 1.5rem 4rem 6rem;
/* Bedeuted das Gleiche wie: */
/* padding-top: 24px;
padding-left: 64px;
padding-right: 64px;
padding-bottom: 96px; */
border: 1px solid magenta;
/* Bedeutet das Gleiche wie: */
/* border-width: 1px;
border-style: solid;
border-color: magenta; */
}
.inner {
background-color: salmon;
height: 6rem;
}

Die „display“-Eigenschaft

Eine der wichtigsten CSS-Eigenschaften ist die Display-Eigenschaft. Sie steuert, was für eine Art von Box der Browser für ein Element generiert und wie diese gelayoutet wird. Wir haben bereits die häufigsten Werte für Display kennengelernt: inline und block, aber es gibt noch ein paar mehr.

Mit display: none; könnt ihr beispielsweise ein Element komplett von der Seite entfernen. Es wird dann weder angezeigt, noch von einem Bildschirmleser vorgelesen. Verwendet ihr hingegen display: grid; oder display: flex; schaltet ihr mächtige Layoutfunktionen für eure Elemente an, die wir uns gleich noch genauer ansehen werden.

Verbergen, aber nicht verstecken

Es kann vorkommen, dass ihr ein Element weiterhin auf eurer Seite anzeigen lassen möchtet, damit es weiterhin den Raum einnimmt, den ihr dafür vorgesehen habt, es aber nicht oder nur teilweise sichtbar sein soll. Dafür gibt es zwei weitere Eigenschaften, die ihr in diesem Fall verwenden könnt, ohne display: none; setzen zu müssen:

  • opacity: Hiermit steuert ihr die Deckkraft. Diese Eigenschaft hat einen Wert zwischen 0 (transparent) und 1 (volle Deckkraft)

  • visibility: Diese Eigenschaft steuert die Sichtbarkeit eines Elements. hidden macht das Element unsichtbar, visible blendet es ein – im Gegensatz zu display: none; nimmt ein Element mit visibility: hidden; weiterhin seinen Platz auf der Website ein

<section class="container">
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box none">Ich bin nicht auf der Seite</div>
<div class="box hidden">Ich bin unsichtbar</div>
<div class="box opacity">Ich bin halbtransparent</div>
</section>
body {
font-family: system-ui, sans-serif;
}
.container {
display: flex;
align-items: center;
justify-content: center;
background-color: salmon;
padding: 1rem;
gap: 1rem;
border-radius: 0.5625rem;
}
.box {
min-width: 8rem;
aspect-ratio: 1;
border: 1px solid white;
padding: 1rem;
background-color: lightsalmon;
border-radius: 0.75rem;
&.none {
display: none;
}
&.hidden {
visibility: hidden;
}
&.opacity {
opacity: 0.5;
}
}

Flexbox-Layout

Mit display: flex; aktiviert ihr das „Flexbox“-Layout für euer HTML-Element. Das verhält sich in etwa so, wie das Auto-Layout in Figma. Ihr könnt einstellen, ob die Kindelemente nebeneinander (Standard) oder untereinander (flex-direction: column;) angezeigt werden sollen, wie viel Abstand zwischen ihnen sein soll (z.B. via gap), wie sie sich ausrichten sollen, und vieles mehr.

Am häufigsten wird dieses Layout für horizontale Elemente verwendet, also z.B. eure Menüleiste, aber auch, um z.B. das Label eines Buttons und ein Icon zueinander zu zentrieren. CSS-Tricks hat einen sehr guten Artikel dazu veröffentlicht, der die vielen verschiedenen Einstellungen bildlich darstellt.

Zum Artikel auf CSS-Tricks

In den meisten Fällen benötigt ihr ein Flexbox-Layout, wenn ihr in eurem Design-Tool ein horizontales Auto-Layout verwendet habt. Vertikale Flex-Layouts werden nicht so häufig verwendet, sind aber auch nützlich. Der größte Nachteil eines Flex-Layouts ist, dass es nur eindimensional funktioniert. Ihr könnt damit nicht Spalten und Zeilen definieren, nur jeweils eins von beidem. Falls ihr beides braucht, benötigt ihr ein Raster.

<h2>Normales Flex</h2>
<section class="container">
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
</section>
<h2>Normales Flex mit wachsenden Kindern</h2>
<section class="container">
<div class="box grow">Ich bin eine gewöhnliche Box</div>
<div class="box grow">Ich bin eine gewöhnliche Box</div>
</section>
<h2>Zentriertes Flex</h2>
<section class="container center">
<div class="box">Ich bin eine kleine Box</div>
<div class="box tall">Ich bin eine hohe Box</div>
</section>
<h2>Stretchy Flex</h2>
<section class="container stretch">
<div class="box">Ich bin eine kleine Box, die so hoch ist wie "hohe Box"</div>
<div class="box tall">Ich bin eine hohe Box</div>
</section>
<h2>Wrappy Flex</h2>
<section class="container wrap">
<div class="box">Ich bin eine kleine Box</div>
<div class="box">Ich bin eine kleine Box</div>
<div class="box">Ich bin eine kleine Box</div>
<div class="box">Ich bin eine kleine Box</div>
<div class="box">Ich bin eine kleine Box</div>
</section>
body {
font-family: system-ui, sans-serif;
}
.container {
display: flex;
background-color: salmon;
padding: 1rem;
gap: 1rem;
border-radius: 0.5625rem;
&.center {
align-items: center;
justify-content: center;
}
&.stretch {
align-items: stretch;
}
&.wrap {
flex-wrap: wrap;
}
}
.box {
min-width: 0;
aspect-ratio: 1;
border: 1px solid white;
padding: 1rem;
background-color: lightsalmon;
border-radius: 0.75rem;
&.tall {
aspect-ratio: 1 / 2;
}
&.grow {
flex-grow: 1;
}
}

Raster mit CSS-Grid

Wenn ein Flexbox-Layout nicht mehr ausreicht, dann könnt ihr zu einem Grid-Layout greifen. Ihr aktiviert es mit display: grid; und signalisiert so, dass ein Eltern-Element seine direkten Kindelemente nach den Regeln des von euch spezifizierten Rasters layouten soll.

Grid-Layouts in CSS könnten allein schon eine komplette Stunde füllen – es ist ein hochflexibles und deshalb auch komplexes Werkzeug, mit dem ihr komplette Rastersysteme definieren könnt. Für den Anfang reicht es aber aus, zu wissen, dass ihr mit grid-template-columns und grid-template-rows die Spalten und Zeilen eures Rasters definieren könnt. Dabei ist auch die repeat()-Funktion sehr nützlich, denn mit ihr könnt ihr mehrere Spalten (oder Zeilen) auf einmal definieren.

Um zum Beispiel das klassische 12-Spalten-Raster zu definieren, würdet ihr grid-template-columns: repeat(12, 1fr); schreiben. Das 1fr steht hierbei für „einen Bruchteil“, d.h. genau 1/12 des verfügbaren Platzes.

Hättet ihr grid-template-columns: 1fr 2fr 1fr; geschrieben, würdet ihr ein Raster mit drei Spalten erhalten, bei dem die mittlere Spalte doppelt so breit wäre wie die erste und die letzte Spalte, denn sie soll ja „zwei Bruchteile“ des verfügbaren Platzes einnehmen.

In welcher Spalte und Zeile Kindelemente platziert werden, steuert ihr mit den Eigenschaften grid-column und grid-row. Das sind Shorthand-Properties für grid-column-start und grid-column-end sowie grid-row-start und grid-row-end. In ihnen gebt ihr an, in welcher Spalte / Zeile das Element beginnen und enden soll. Ihr könnt hier sowohl mit positiven, als auch mit negativen Spalten- / Zeilenzahlen arbeiten. Negative Zahlen zählen immer vom Ende des Rasters ausgehend.

So würde grid-column: 1 / 3; ein Element von Spalte 1 bis Spalte 3 im Raster platzieren. grid-column: 2 / -1; hingegen würde das Element von Spalte 2 bis zur letzten Spalte platzieren. Mit dem speziellen Zusatz span könnt ihr außerdem ausgehend von der Startspalte mehrere Spalten/Zeilen überspannen. So würde grid-row: 1 / span 3 ein Element von der ersten Zeile bis zur dritten Zeile spannen. Der Vorteil hiervon ist, dass ihr grid-column-start so flexibel verändern könnt, das Element aber immer drei Zeilen überspannen wird.

Wie ihr seht, ist CSS-Grid ein sehr mächtiges Layoutwerkzeug, das euch viele Freiheiten gibt – aber versucht trotzdem nicht, zu sehr in die automatischen Layoutvorgänge des Browsers einzugreifen. Jedes Mal, wenn ihr grid-column oder grid-row händisch setzt, besteht das Potenzial, dass etwas kaputtgeht, wenn sich euer Raster oder die Größe des Browserfensters verändert.

Außerdem ist es in den meisten Fällen völlig ausreichend, nur die Spalten eures Rasters zu definieren und den Browser die Zeilen automatisch setzen zu lassen. Falls ihr die Höhe dieser automatischen Zeilen verändern möchtet, könnt ihr das über die grid-auto-rows-Eigenschaft tun.

Abstände zwischen Spalten und Zeilen könnt ihr (wie auch in Flex) mit der Eigenschaft gap setzen, die eine Shorthand für column-gap und row-gap ist. Und wie für Flex, hat CSS-Tricks auch für Grid einen illustrierten Artikel vorbereitet, der euch sehr viele verschiedene und fortgeschrittene Features dieses Layoutwerkzeugs zeigt:

Zum Artikel auf CSS-Tricks

Versucht euch nicht von Grid abschrecken zu lassen. Es ist vergleichsweise kompliziert, aber die meisten Raster lassen sich schon nur mit grid-template-columns und gap aufbauen – probiert es einfach mal selbst aus!

<h2>Vierspaltiges Raster</h2>
<section class="container">
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box span-2">Ich bin eine Box, die zwei Spalten und Zeilen überspannt</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
</section>
<h2>Dynamisches Raster</h2>
<section class="container dynamo">
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box span-2">Ich bin eine Box, die zwei Spalten und Zeilen überspannt</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
<div class="box">Ich bin eine gewöhnliche Box</div>
</section>
body {
font-family: system-ui, sans-serif;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
background-color: salmon;
padding: 1rem;
gap: 1rem;
border-radius: 1.75rem;
&.dynamo {
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
}
}
.box {
min-width: 0;
aspect-ratio: 1;
border: 1px solid white;
padding: 1rem;
background-color: lightsalmon;
border-radius: 0.75rem;
&.span-2 {
aspect-ratio: auto;
grid-column-end: span 2;
grid-row-end: span 2;
}
}

Zwischenpräsentation

Bitte bereitet für den 21.11. eine kleine Zwischenpräsentation eurer Website vor. In ca. 5 Minuten sollt ihr der Gruppe und mir eure Desktop- und Mobile-Designs vorstellen. Wir können dann gemeinsam Feedback geben und uns über die Machbarkeit unterhalten.

Praxis

Für die heutige Praxis legt ihr euch bitte ein Raster aus Bildern (nehmt gerne Platzhalter von Lorem-Picsum) an, damit ihr ein bisschen mit CSS-Grid experimentieren könnt. Versucht zum Beispiel auch, ein Bild über mehrere Spalten und / oder Zeilen zu spannen.

Außerdem ist nun der ideale Zeitpunkt, die Hauptschriftart für eure Website einzurichten. Versucht also, wie im Unterricht besprochen und hier im Skript beschrieben, eine fonts.css-Datei anzulegen und eure Schriftart mit @fontface einzurichten. Verlinkt dann die fonts.css-Datei in eurem HTML-Dokument und setzt die Schriftart im body-Selektor eures Stylesheets, um zu sehen, ob ihr die Schrift richtig eingebettet habt.