Abschnitt 5 · Lektion 4
Custom Properties
Bis hierher stand jeder Wert dort, wo er wirkt. Bei einer Karte geht das gut. Bei einer Seite mit vier Komponenten, die dieselbe Akzentfarbe benutzen, wird daraus eine Suchaufgabe, sobald sich die Farbe ändert.
Custom Properties lösen das: du gibst einem Wert einen Namen und verweist danach nur noch auf den Namen.
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. Ändere oben eine Zahl
und alles, was sie benutzt, geht mit. */
.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. Warum nicht gleich html schreiben: :root hat eine höhere Spezifität (0-1-0 statt 0-0-1) und macht beim Lesen sofort klar, dass hier etwas Globales steht.
Der Name ist frei wählbar, aber er unterscheidet Groß- und Kleinschreibung. --Farbe und --farbe sind zwei verschiedene Variablen, und das fällt einem erst nach zehn Minuten auf.
Sie vererben sich
Das ist der Punkt, an dem Custom Properties mehr sind als eine Abkürzung.
Sie verhalten sich wie color oder font-size: 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 Variable 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.
Das ist das Muster, das den ganzen Rest des Kurses trägt: Regeln stehen einmal da, Varianten sind andere Werte. In Lektion 12.6 schaltet derselbe Mechanismus die ganze Seite auf Dunkelmodus um, mit vier geänderten Zeilen.
Was sie von Sass-Variablen unterscheidet
Wer schon einmal Sass oder Less gesehen hat, kennt Variablen mit einem Dollarzeichen. Die sehen ähnlich aus und sind etwas grundlegend anderes.
Sass-Variablen werden beim Übersetzen eingesetzt und sind danach weg. Im Browser steht die fertige Zahl.
Custom Properties leben zur Laufzeit. Du kannst sie per Media Query umschalten, per Klasse überschreiben, und JavaScript kann sie setzen. Alles, was sie benutzt, folgt sofort.
Noch eine Eigenheit: bis zum Einsetzen sind sie nur Text. Der Browser prüft beim Deklarieren gar nicht, ob der Wert sinnvoll ist. Deshalb funktioniert auch so etwas wie --luft: 8px mitten in einer Rechnung, und deshalb lässt sich sogar ein halber Wert in einer Variablen ablegen.
Wenn der Wert nicht passt
var() nimmt ein zweites Argument: den Fallback, der gilt, wenn es die Variable gar nicht gibt.
<div class="kasten eins">Variable gibt es nicht, der Fallback greift</div>
<div class="kasten zwei">Variable ist da, der Fallback bleibt liegen</div>
<div class="kasten drei">Variable 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 Variable nicht gibt. */
.eins {
background-color: var(--gibt-es-nicht, #52525b);
}
.zwei {
--farbe: #2563eb;
background-color: var(--farbe, #52525b);
}
/* 12px ist keine Farbe. Die Variable existiert 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
Anfangswert 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);
} Und jetzt die Stelle, an der die Intuition trügt, und du siehst sie im dritten Kasten des Beispiels. Der Fallback greift nur bei einer fehlenden Variablen. Ist die Variable da, aber ihr Wert für diese Eigenschaft unbrauchbar, passiert etwas anderes: die Deklaration fällt auf den geerbten Wert zurück, oder auf den Anfangswert der Eigenschaft. Bei background-color ist das transparent, deshalb steht der dritte Kasten ohne Hintergrund da. Nicht auf den Fallback.
Das ist selten, aber wenn es passiert, sucht man lange. Der Grund liegt in der Reihenfolge: der Browser setzt den Text der Variablen zuerst ein und stellt erst danach fest, dass die Deklaration ungültig ist. Zu dem Zeitpunkt war der Fallback längst nicht mehr im Spiel.
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.