Abschnitt 5 · Lektion 4
Custom Properties
Vier Komponenten mit derselben Akzentfarbe machen aus einer neuen Farbe eine Suchaufgabe. Solange jeder Wert dort steht, wo er wirkt, musst du ihn an vier Stellen finden.
Custom Properties, oft CSS-Variablen genannt, lösen das. Ein Wert bekommt einen Namen, und danach steht nur noch der Name da.
Deklarieren und einsetzen
Eine Custom Property ist eine ganz normale CSS-Deklaration, deren Name mit zwei Bindestrichen beginnt. Eingesetzt wird sie mit var().
<div class="karte">
<h3>Portfolio</h3>
<p>Farbe, Abstand und Radius stehen nur an einer Stelle.</p>
</div> /* :root ist das html-Element. Hier oben stehen die Werte
einmal, mit sprechenden Namen. */
:root {
--farbe-akzent: #2563eb;
--abstand: 24px;
--radius: 12px;
}
/* Ab hier wird nur noch verwiesen. Ändert sich oben eine
Zahl, geht alles mit, was sie benutzt. */
.karte {
border: 2px solid var(--farbe-akzent);
border-radius: var(--radius);
padding: var(--abstand);
}
.karte h3 {
margin-top: 0;
color: var(--farbe-akzent);
} :root ist eine Pseudoklasse für das Wurzelelement, also für html. Man könnte genauso gut html schreiben. :root hat aber eine höhere Spezifität (0-1-0 statt 0-0-1), und beim Lesen ist sofort klar, dass hier etwas Globales steht.
Den Namen darfst du frei wählen, nur Groß- und Kleinschreibung zählen mit. --Farbe und --farbe sind zwei verschiedene Custom Properties, und das fällt einem erst nach zehn Minuten auf.
Sie vererben sich
Hier werden Custom Properties mehr als eine Abkürzung.
Sie verhalten sich wie color oder font-size, und der Wert wandert an alle Kinder weiter. Setzt du ihn an einem Element neu, gilt der neue Wert ab dort nach unten, und überall sonst bleibt der alte stehen.
<div class="karte">
<h3>Normal</h3>
<p>Nimmt den Wert von der Wurzel.</p>
</div>
<div class="karte karte--wichtig">
<h3>Wichtig</h3>
<p>Dieselben Regeln, eine Custom Property anders.</p>
</div> :root {
--farbe-akzent: #2563eb;
}
.karte {
border: 2px solid var(--farbe-akzent);
padding: 16px;
margin-bottom: 12px;
}
.karte h3 {
margin-top: 0;
color: var(--farbe-akzent);
}
/* Eine einzige Zeile, und Rahmen und Titel wechseln
gemeinsam. Es gibt keine zweite Regel für die Variante. */
.karte--wichtig {
--farbe-akzent: #b91c1c;
} Die hervorgehobene Variante hat genau eine Deklaration, und trotzdem ändern sich Rahmen und Titel. Es gibt keine zweite Regel, die beschreibt, wie eine wichtige Karte aussieht. Es gibt nur einen anderen Wert an einer Stelle.
Auf diesem Muster baut der Rest des Kurses auf. Eine Regel steht einmal da, eine Variante ist nur ein anderer Wert. In Lektion 12.6 wird auf demselben Weg die ganze Seite auf Dunkelmodus umgeschaltet, ohne dass sich eine Regel darunter ändert.
Was sie von Sass-Variablen unterscheidet
Wenn du schon einmal Sass oder Less gesehen hast, kennst du Variablen mit einem Dollarzeichen. Die sehen ähnlich aus, sind aber etwas grundlegend anderes.
Sass-Variablen werden beim Übersetzen eingesetzt und sind danach weg. Im Browser steht die fertige Zahl.
Custom Properties gibt es dagegen auch noch zur Laufzeit, also wenn die Seite im Browser offen ist. Du kannst sie per Media Query umschalten, per Klasse überschreiben, und JavaScript kann sie setzen. Alles, was sie benutzt, zieht sofort nach.
Bis zum Einsetzen sind sie außerdem nur Text. Der Browser prüft beim Deklarieren gar nicht, ob der Wert sinnvoll ist. Deshalb funktioniert so etwas wie --luft: 8px mitten in einer Rechnung. Man kann sogar einen halben Wert in einer Custom Property ablegen.
Wenn der Wert nicht passt
var() nimmt ein zweites Argument, einen Fallback, also einen Ersatzwert. Er gilt, wenn es die Custom Property gar nicht gibt.
<div class="kasten eins">Custom Property fehlt, der Fallback greift</div>
<div class="kasten zwei">Custom Property ist da, der Fallback bleibt liegen</div>
<div class="kasten drei">Custom Property ist da und unbrauchbar, der Fallback greift trotzdem nicht</div> .kasten {
padding: 12px;
margin-bottom: 8px;
color: #ffffff;
}
/* Zweites Argument von var(): was gelten soll,
wenn es die Custom Property nicht gibt. */
.eins {
background-color: var(--gibt-es-nicht, #52525b);
}
.zwei {
--farbe: #2563eb;
background-color: var(--farbe, #52525b);
}
/* 12px ist keine Farbe. Die Custom Property gibt es aber,
also setzt var() ihren Wert ein, und der Fallback
kommt gar nicht erst zum Zug. Übrig bleibt eine
unbrauchbare Deklaration, und die fällt auf den
Standardwert zurück: transparent. Deshalb hat der
dritte Kasten gar keinen Hintergrund, und deshalb
braucht er hier eine dunkle Schrift. */
.drei {
--farbe: 12px;
color: #18181b;
background-color: var(--farbe, #52525b);
} Beim dritten Kasten im Beispiel trügt die Intuition. Der Fallback greift nur bei einer fehlenden Custom Property. Ist sie da, aber ihr Wert für diese Eigenschaft unbrauchbar, passiert etwas anderes. Die Deklaration fällt dann auf den geerbten Wert zurück oder auf den Standardwert der Eigenschaft. Auf den Fallback jedenfalls nicht. Bei background-color ist der Standardwert transparent, und deshalb steht der dritte Kasten ohne Hintergrund da.
Das kommt selten vor, aber wenn es passiert, sucht man lange. Der Grund liegt in der Reihenfolge. Der Browser setzt den Text zuerst ein und merkt erst danach, dass die Deklaration ungültig ist, und da ist es für den Fallback schon zu spät.
In der Aufgabe soll ein zweiter Button anders aussehen, ohne dass seine Regel ein zweites Mal dasteht.
Zum Mitnehmen
Custom Properties vererben sich wie normale Eigenschaften. Deshalb setzt du sie einmal auf :root und überschreibst sie lokal genau an der Komponente, die anders aussehen soll.
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.