Verwendung von CSS-Custom-Properties (Variablen)
Custom Properties (manchmal auch CSS-Variablen oder kaskadierende Variablen genannt) sind von CSS-Autoren definierte Entitäten, die spezifische Werte darstellen, die im gesamten Dokument wiederverwendet werden können. Sie werden mit der @property
-At-Regel oder durch Custom-Property-Syntax (z.B. --primary-color: blue;
) gesetzt. Der Zugriff auf Custom Properties erfolgt über die CSS-var()
-Funktion (z.B. color: var(--primary-color);
).
Komplexe Websites verfügen über sehr große Mengen an CSS, was häufig zu vielen sich wiederholenden CSS-Werten führt. Zum Beispiel ist es üblich, dass die gleiche Farbe an Hunderten von verschiedenen Stellen in Stylesheets verwendet wird. Das Ändern einer Farbe, die an vielen Stellen dupliziert wurde, erfordert eine Suche und Ersetzung in allen Regeln und CSS-Dateien. Custom Properties ermöglichen es, einen Wert an einer Stelle zu definieren und ihn dann an mehreren anderen Stellen zu referenzieren, wodurch die Arbeit erleichtert wird. Ein weiterer Vorteil ist die Lesbarkeit und Semantik. Zum Beispiel ist --main-text-color
leichter zu verstehen als die hexadezimale Farbe #00ff00
, besonders wenn die Farbe in unterschiedlichen Kontexten verwendet wird.
Custom Properties, die mithilfe von zwei Bindestrichen (--
) definiert werden, unterliegen der Kaskade und erben ihren Wert vom übergeordneten Element. Die @property
-At-Regel ermöglicht eine genauere Kontrolle über die Custom Property und erlaubt es, festzulegen, ob sie ihren Wert vom Elternteil erbt, welchen Anfangswert sie hat und welche Typbeschränkungen gelten sollen.
Hinweis: Variablen funktionieren nicht innerhalb von Media Queries und Container Queries.
Sie können die var()
-Funktion in jedem Teil eines Wertes in jeder Eigenschaft auf einem Element verwenden.
Sie können var()
nicht für Eigenschaftsnamen, Selektoren oder alles außer Eigenschaftswerten verwenden, was bedeutet, dass Sie es nicht in einer Media Query oder Container Query verwenden können.
Deklaration von Custom Properties
In CSS können Sie eine Custom Property mit zwei Bindestrichen als Präfix für den Eigenschaftsnamen oder mithilfe der @property
-At-Regel deklarieren. Die folgenden Abschnitte beschreiben, wie Sie diese beiden Methoden verwenden.
Verwenden eines Präfixes von zwei Bindestrichen (--
)
Eine Custom Property, die mit zwei Bindestrichen versehen ist, beginnt mit --
, gefolgt vom Eigenschaftsnamen (z.B. --my-property
) und einem Eigenschaftswert, der ein gültiger CSS-Wert sein kann. Wie jede andere Eigenschaft wird dies innerhalb eines Regelsets geschrieben. Das folgende Beispiel zeigt, wie eine Custom Property --main-bg-color
erstellt wird und einen <named-color>
-Wert von brown
verwendet:
section {
--main-bg-color: brown;
}
Der dem Regelset gegebene Selektor (<section>
-Elemente im obigen Beispiel) definiert den Bereich, in dem die Custom Property verwendet werden kann. Aus diesem Grund ist es üblich, Custom Properties auf der :root
-Pseudoklasse zu definieren, sodass sie global referenziert werden kann:
:root {
--main-bg-color: brown;
}
Dies muss jedoch nicht immer der Fall sein: Vielleicht haben Sie einen guten Grund, die Reichweite Ihrer Custom Properties zu begrenzen.
Hinweis: Custom Property-Namen sind case-sensitive — --my-color
wird als separate Custom Property von --My-color
behandelt.
Verwendung der @property
-At-Regel
Die @property
-At-Regel ermöglicht es Ihnen, die Definition einer Custom Property präziser zu gestalten, indem Sie eine Typzuordnung mit der Eigenschaft ermöglichen, Standardwerte festlegen und die Vererbung steuern. Das folgende Beispiel erstellt eine Custom Property mit dem Namen --logo-color
, die einen <color>
erwartet:
@property --logo-color {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
Wenn Sie Custom Properties nicht direkt in CSS, sondern in JavaScript definieren oder verwenden möchten, gibt es eine entsprechende API zu diesem Zweck. Sie können auf der Seite CSS Properties and Values API nachlesen, wie das funktioniert.
Referenzieren von Custom Properties mit var()
Unabhängig davon, welche Methode Sie zur Definition einer Custom Property wählen, verwenden Sie sie, indem Sie die Eigenschaft in einer var()
-Funktion anstelle eines Standard-Eigenschaftswertes referenzieren:
details {
background-color: var(--main-bg-color);
}
Erste Schritte mit Custom Properties
Beginnen wir mit etwas HTML, dem wir einige Stile zuweisen möchten. Es gibt ein <div>
, das als Container fungiert und einige Kindelemente enthält, darunter einige mit verschachtelten Elementen:
<div class="container">
<div class="one">
<p>One</p>
</div>
<div class="two">
<p>Two</p>
<div class="three">
<p>Three</p>
</div>
</div>
<input class="four" placeholder="Four" />
<textarea class="five">Five</textarea>
</div>
Wir werden das folgende CSS verwenden, um einige verschiedene Elemente basierend auf ihren Klassen zu stylen (einige Layout-Regeln werden unten nicht angezeigt, damit wir uns auf die Farben konzentrieren können). Abhängig von ihren Klassen vergeben wir den Elementen Hintergrundfarben von cornflowerblue
oder aquamarine
:
/* For each class, set some colors */
.one {
background-color: cornflowerblue;
}
.two {
color: black;
background-color: aquamarine;
}
.three {
background-color: cornflowerblue;
}
.four {
background-color: cornflowerblue;
}
.five {
background-color: cornflowerblue;
}
Dies ergibt das folgende Ergebnis:
Es besteht die Möglichkeit, Custom Properties zu verwenden, um sich wiederholende Werte in diesen Regeln zu ersetzen. Nach der Definition von --main-bg-color
im .container
-Bereich und der Referenzierung seines Wertes an mehreren Stellen sehen die aktualisierten Stile so aus:
/* Define --main-bg-color here */
.container {
--main-bg-color: cornflowerblue;
}
/* For each class, set some colors */
.one {
background-color: var(--main-bg-color);
}
.two {
color: black;
background-color: aquamarine;
}
.three {
background-color: var(--main-bg-color);
}
.four {
background-color: var(--main-bg-color);
}
.five {
background-color: var(--main-bg-color);
}
Verwendung der :root-Pseudoklasse
Für einige CSS-Deklarationen ist es möglich, diese höher in der Kaskade zu deklarieren und das CSS-Erbe dieses Problem lösen zu lassen. Für nicht triviale Projekte ist dies nicht immer möglich. Indem man eine Custom Property auf der :root
-Pseudoklasse deklariert und sie dort verwendet, wo sie im gesamten Dokument benötigt wird, kann ein CSS-Autor die Notwendigkeit von Wiederholungen verringern:
/* Define --main-bg-color here */
:root {
--main-bg-color: cornflowerblue;
}
/* For each class, set some colors */
.one {
background-color: var(--main-bg-color);
}
.two {
color: black;
background-color: aquamarine;
}
.three {
background-color: var(--main-bg-color);
}
.four {
background-color: var(--main-bg-color);
}
.five {
background-color: var(--main-bg-color);
}
Dies führt zum gleichen Ergebnis wie im vorherigen Beispiel, erlaubt aber eine einzige kanonische Deklaration des gewünschten Eigenschaftswerts (--main-bg-color: cornflowerblue;
), was äußerst nützlich ist, wenn Sie den Wert später im gesamten Projekt ändern möchten.
Vererbung von Custom Properties
Eine Custom Property, die mit zwei Bindestrichen --
anstelle von @property
definiert wird, erbt immer den Wert ihres Elternteils. Dies wird im folgenden Beispiel demonstriert:
<div class="one">
<p>One</p>
<div class="two">
<p>Two</p>
<div class="three"><p>Three</p></div>
<div class="four"><p>Four</p></div>
</div>
</div>
div {
background-color: var(--box-color);
}
.two {
--box-color: cornflowerblue;
}
.three {
--box-color: aquamarine;
}
Die Ergebnisse von var(--box-color)
, abhängig von der Vererbung, sind wie folgt:
class="one"
: Ungültiger Wert, was der Standardwert einer auf diese Weise definierten Custom Property istclass="two"
:cornflowerblue
class="three"
:aquamarine
class="four"
:cornflowerblue
(von seinem Elternteil geerbt)
Ein Aspekt von Custom Properties, den die obigen Beispiele zeigen, ist, dass sie sich nicht genau wie Variablen in anderen Programmiersprachen verhalten. Der Wert wird dort berechnet, wo er benötigt wird, und nicht gespeichert und an anderen Stellen eines Stylesheets wiederverwendet. Beispielsweise können Sie den Wert einer Eigenschaft nicht setzen und erwarten, ihn in der Regel eines Nachfahren eines Geschwisters abzurufen. Die Eigenschaft ist nur für den passenden Selektor und seine Nachkommen festgelegt.
Verwendung von @property
zur Steuerung der Vererbung
Die @property
-At-Regel lässt Sie explizit angeben, ob die Eigenschaft vererbt wird oder nicht. Das folgende Beispiel erstellt eine Custom Property mithilfe der @property
-At-Regel. Die Vererbung ist deaktiviert, es ist ein <color>
-Datentyp definiert, und ein Anfangswert von cornflowerblue
ist festgelegt.
Das Elternelement setzt --box-color
auf einen Wert von green
und verwendet --box-color
als Wert für seine Hintergrundfarbe. Das Kindelement verwendet ebenfalls background-color: var(--box-color)
, und wir würden erwarten, dass es die Farbe green
hat, wenn die Vererbung aktiviert wäre (oder wenn es mit der Doppelstrichsyntax definiert wurde).
<div class="parent">
<p>Parent element</p>
<div class="child">
<p>Child element with inheritance disabled for --box-color.</p>
</div>
</div>
@property --box-color {
syntax: "<color>";
inherits: false;
initial-value: cornflowerblue;
}
.parent {
--box-color: green;
background-color: var(--box-color);
}
.child {
width: 80%;
height: 40%;
background-color: var(--box-color);
}
Da inherits: false;
in der At-Regel gesetzt ist und ein Wert für die --box-color
-Eigenschaft nicht im .child
-Bereich deklariert ist, wird der Anfangswert von cornflowerblue
anstelle von green
verwendet, der vom Elternteil geerbt worden wäre:
Fallback-Werte für Custom Properties
Sie können Fallback-Werte für Custom Properties mit der var()
-Funktion und dem initial-value
der @property
-At-Regel definieren.
Hinweis: Fallback-Werte werden nicht verwendet, um Kompatibilitätsprobleme zu beheben, wenn CSS-Custom-Properties nicht unterstützt werden, da der Fallback-Wert in diesem Fall nicht hilft. Fallbacks decken den Fall ab, in dem der Browser CSS-Custom-Properties unterstützt und in der Lage ist, einen anderen Wert zu verwenden, wenn die gewünschte Variable noch nicht definiert ist oder einen ungültigen Wert hat.
Festlegen von Fallbacks in der var()
-Funktion
Mithilfe der var()
-Funktion können Sie mehrere Fallback-Werte definieren, wenn die angegebene Variable noch nicht definiert ist; dies kann nützlich sein, wenn Sie mit Custom Elements und Shadow DOM arbeiten.
Das erste Argument der Funktion ist der Name der Custom Property. Das zweite Argument der Funktion ist ein optionaler Fallback-Wert, der als Ersatzwert verwendet wird, wenn die referenzierte Custom Property ungültig ist. Die Funktion akzeptiert zwei Parameter, wobei alles nach dem ersten Komma als zweiter Parameter zugeordnet wird. Wenn der zweite Parameter ungültig ist, schlägt der Fallback fehl. Beispiel:
.one {
/* Red if --my-var is not defined */
color: var(--my-var, red);
}
.two {
/* pink if --my-var and --my-background are not defined */
color: var(--my-var, var(--my-background, pink));
}
.three {
/* Invalid: "--my-background, pink" */
color: var(--my-var, --my-background, pink);
}
Das Einschließen einer Custom Property als Fallback, wie im zweiten Beispiel oben zu sehen (var(--my-var, var(--my-background, pink))
), ist die richtige Methode, um mehr als einen Fallback mit var()
bereitzustellen. Sie sollten sich jedoch der Auswirkungen dieser Methode auf die Performance bewusst sein, da es mehr Zeit in Anspruch nimmt, die verschachtelten Variablen zu parsen.
Hinweis: Die Syntax des Fallbacks, wie die von Custom Properties, erlaubt Kommata. Zum Beispiel definiert var(--foo, red, blue)
einen Fallback von red, blue
— alles zwischen dem ersten Komma und dem Ende der Funktion wird als Fallback-Wert betrachtet.
Fallbacks mit dem @property
-Anfangswert
Neben der Verwendung von var()
kann das initial-value
, das in der @property
-At-Regel definiert ist, als Fallback-Mechanismus verwendet werden. Tatsächlich haben wir dies bereits im Abschnitt @property
-Vererbung gesehen.
Das folgende Beispiel setzt einen Anfangswert von --box-color
auf cornflowerblue
mithilfe der @property
-At-Regel. Im Regelset, das auf die At-Regel folgt, möchten wir --box-color
auf aquamarine
setzen, aber es gibt einen Tippfehler im Wertnamen. Das Gleiche gilt für das dritte <div>
, wo wir 2rem
für die Custom Property verwendet haben, die einen gültigen <color>
-Wert erwartet. Sowohl 2rem
als auch aqumarine
sind ungültige Farbwerte, daher wird der Anfangswert von cornflowerblue
angewendet:
@property --box-color {
syntax: "<color>";
initial-value: cornflowerblue;
inherits: false;
}
.one {
--box-color: aquamarine;
background-color: var(--box-color);
}
.two {
--box-color: aqumarine;
background-color: var(--box-color);
}
.three {
--box-color: 2rem;
background-color: var(--box-color);
}
Ungültige Custom Properties
Jede CSS-Eigenschaft kann einem definierten Satz von Werten zugewiesen werden. Wenn Sie versuchen, einer Eigenschaft einen Wert zuzuweisen, der außerhalb ihres Satzes gültiger Werte liegt, wird er als ungültig angesehen.
Wenn der Browser einen ungültigen Wert für eine reguläre CSS-Eigenschaft (z. B. einen Wert von 16px
für die color
-Eigenschaft) antrifft, verwirft er die Deklaration, und den Elementen werden die Werte zugewiesen, die sie gehabt hätten, wenn die Deklaration nicht existiert hätte. Im folgenden Beispiel sehen wir, was passiert, wenn eine reguläre CSS-Deklaration ungültig ist; color: 16px;
wird verworfen und die vorherige color: blue
-Regel wird stattdessen angewendet:
<p>This paragraph is initially black.</p>
p {
color: blue;
}
p {
/* oops, not a valid color */
color: 16px;
}
Wenn jedoch die Werte von Custom Properties geparst werden, weiß der Browser noch nicht, wo sie verwendet werden, und muss daher fast alle Werte als gültig betrachten. Leider können diese gültigen Werte in einem Zusammenhang, in dem sie keinen Sinn ergeben, verwendet werden, was zu ungültigen CSS-Anweisungen führen kann und zum Konzept des bei Berechnungszeitpunkt gültig wird.
Wenn der Browser auf eine ungültige var()
-Substitution trifft, wird der anfängliche oder vererbte Wert der Eigenschaft verwendet. Dieses Beispiel ist genau wie das letzte, außer dass wir eine Custom Property verwenden.
Der Browser ersetzt den Wert von --text-color
durch var(--text-color)
, aber 16px
ist kein gültiger Eigenschaftswert für color
. Nach der Ersetzung macht die Eigenschaft keinen Sinn, daher behandelt der Browser diese Situation in zwei Schritten:
- Überprüfen Sie, ob die Eigenschaft
color
erbbar ist. Sie ist es, aber dieses<p>
hat keinen Elternteil mit der festgelegtencolor
-Eigenschaft. Gehen Sie also zum nächsten Schritt über. - Setzen Sie den Wert auf seinen Standardanfangswert, der schwarz ist.
<p>This paragraph is initially black.</p>
:root {
--text-color: 16px;
}
p {
color: blue;
}
p {
color: var(--text-color);
}
Für solche Fälle kann die @property
-At-Regel unerwartete Ergebnisse verhindern, indem sie den Anfangswert der Eigenschaft definiert:
<p>This paragraph is initially black.</p>
@property --text-color {
syntax: "<color>";
inherits: false;
initial-value: cornflowerblue;
}
:root {
--text-color: 16px;
}
p {
color: blue;
}
p {
color: var(--text-color);
}
Werte in JavaScript
Um die Werte von Custom Properties in JavaScript zu verwenden, ist es wie bei Standard-Eigenschaften.
// get variable from inline style
element.style.getPropertyValue("--my-var");
// get variable from wherever
getComputedStyle(element).getPropertyValue("--my-var");
// set variable on inline style
element.style.setProperty("--my-var", jsVar + 4);