Verwenden von CSS-Custom-Properties (Variablen)
Custom-Properties (manchmal als CSS-Variablen oder kaskadierende Variablen bezeichnet) sind von CSS-Autoren definierte Entitäten, die spezifische Werte repräsentieren, um sie im gesamten Dokument wiederzuverwenden. Sie werden mit der @property Regel oder durch Custom-Property-Syntax (z.B. --primary-color: blue;) festgelegt. Auf Custom-Properties wird mit der CSS-Funktion var() zugegriffen (z.B. color: var(--primary-color);).
Komplexe Webseiten enthalten oft sehr große Mengen an CSS, was häufig zu vielen sich wiederholenden CSS-Werten führt. Beispielsweise ist es üblich, dieselbe Farbe an Hunderten von verschiedenen Stellen in den Stylesheets zu sehen. Eine Farbe zu ändern, die an vielen Stellen dupliziert wurde, erfordert ein Suchen und Ersetzen über alle Regeln und CSS-Dateien. Custom-Properties erlauben es, einen Wert an einer Stelle zu definieren und dann an mehreren anderen Stellen zu referenzieren, was die Arbeit erleichtert. 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 verschiedenen Kontexten verwendet wird.
Custom-Properties, die mit zwei Bindestrichen (--) definiert wurden, unterliegen der Kaskade und erben ihren Wert von ihrem Elternteil.
Die @property Regel ermöglicht mehr Kontrolle über die Custom-Property und lässt Sie angeben, ob sie ihren Wert von einem Elternteil erbt, welcher Anfangswert gilt und welche Typbeschränkungen angewendet werden sollten.
Hinweis:
Variablen funktionieren nicht innerhalb von Media Queries und Container Queries.
Sie können die Funktion var() in jedem Teil eines Werts in jeder Eigenschaft eines Elements verwenden.
Sie können var() jedoch nicht für Eigenschaftsnamen, Selektoren oder etwas anderes als Eigenschaftswerte verwenden, was bedeutet, dass Sie sie 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 durch die @property Regel deklarieren.
Die folgenden Abschnitte beschreiben, wie diese beiden Methoden verwendet werden.
Verwendung eines Präfixes von zwei Bindestrichen (--)
Eine Custom-Property, die mit zwei Bindestrichen vorangestellt ist, beginnt mit --, gefolgt vom Eigenschaftsnamen (z.B. --my-property) und einem Eigenschaftswert, der jeder gültige CSS-Wert sein kann.
Wie jede andere Eigenschaft wird dies innerhalb eines Regelwerkes geschrieben.
Das folgende Beispiel zeigt, wie man eine Custom-Property --main-bg-color erstellt und einen <named-color> Wert von brown verwendet:
section {
--main-bg-color: brown;
}
Der dem Regelwerk gegebene Selektor (Elemente vom Typ <section> im obigen Beispiel) definiert den Anwendungsbereich, in dem die Custom-Property verwendet werden kann.
Aus diesem Grund ist es eine gängige Praxis, Custom-Properties auf der :root Pseudo-Klasse zu definieren, damit sie global referenziert werden können:
:root {
--main-bg-color: brown;
}
Dies muss nicht immer der Fall sein: Vielleicht haben Sie einen guten Grund, den Anwendungsbereich Ihrer Custom-Properties zu begrenzen.
Hinweis:
Custom-Property-Namen sind case-sensitive — --my-color wird als eine andere Custom-Property behandelt als --My-color.
Verwendung der @property Regel
Die @property Regel ermöglicht Ihnen, ausdrucksvoller bei der Definition einer Custom-Property zu sein, indem Sie der Eigenschaft einen Typ zuordnen, Standardwerte festlegen und die Vererbung steuern.
Das folgende Beispiel erstellt eine Custom-Property namens --logo-color, die einen <color> erwartet:
@property --logo-color {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
Wenn Sie Custom-Properties lieber in JavaScript statt direkt in CSS definieren oder verwenden möchten, gibt es eine entsprechende API zu diesem Zweck. Wie dies funktioniert, können Sie auf der Seite CSS Properties and Values API nachlesen.
Referenzierung von Custom-Properties mit var()
Unabhängig davon, welche Methode Sie zur Definition einer Custom-Property wählen, verwenden Sie sie, indem Sie die Property in einer var() Funktion anstelle eines Standard-Eigenschaftswerts referenzieren:
details {
background-color: var(--main-bg-color);
}
Erste Schritte mit Custom-Properties
Beginnen wir mit etwas HTML, auf das wir einige Stile anwenden möchten.
Es gibt ein <div>, das als Container fungiert und einige Kind-Elemente enthält, 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 gezeigt, damit wir uns auf die Farben konzentrieren können).
Je nach Klassen geben wir Elementen Hintergrundfarben teal oder pink:
/* For each class, set some colors */
.one {
background-color: teal;
}
.two {
color: black;
background-color: pink;
}
.three {
color: white;
background-color: teal;
}
.four {
background-color: teal;
}
.five {
background-color: teal;
}
Dies ergibt folgendes Ergebnis:
Es gibt die Möglichkeit, Custom-Properties zu verwenden, um sich wiederholende Werte in diesen Regeln zu ersetzen.
Nachdem --main-bg-color im .container-Bereich definiert wurde und sein Wert an mehreren Stellen referenziert wird, sehen die aktualisierten Stile folgendermaßen aus:
/* Define --main-bg-color here */
.container {
--main-bg-color: teal;
}
/* For each class, set some colors */
.one {
background-color: var(--main-bg-color);
}
.two {
color: black;
background-color: pink;
}
.three {
color: white;
background-color: var(--main-bg-color);
}
.four {
background-color: var(--main-bg-color);
}
.five {
background-color: var(--main-bg-color);
}
Verwendung der :root Pseudo-Klasse
Bei einigen CSS-Deklarationen ist es möglich, diese höher in der Kaskade zu deklarieren und CSS-Vererbung das Problem lösen zu lassen. Für nicht-triviale Projekte ist dies nicht immer möglich. Durch die Deklaration einer Custom-Property auf der :root Pseudo-Klasse und deren Verwendung an benötigten Stellen im gesamten Dokument, kann ein CSS-Autor die Notwendigkeit von Wiederholungen reduzieren:
/* Define --main-bg-color here */
:root {
--main-bg-color: teal;
}
/* For each class, set some colors */
.one,
.three,
.four,
.five {
background-color: var(--main-bg-color);
}
.two {
color: black;
background-color: pink;
}
Dies führt zum gleichen Ergebnis wie das vorherige Beispiel, ermöglicht jedoch eine kanonische Deklaration des gewünschten Eigenschaftswerts (--main-bg-color: teal;), was sehr nützlich ist, wenn Sie den Wert später im gesamten Projekt ändern möchten.
Vererbung von Custom-Properties
Eine mit zwei Bindestrichen -- statt @property definierte Custom-Property 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: teal;
}
.three {
--box-color: pink;
}
Die Ergebnisse von var(--box-color) in Abhängigkeit von der Vererbung sind wie folgt:
class="one": ungültiger Wert, was der Standardwert einer auf diese Weise definierten Custom-Property istclass="two":tealclass="three":pinkclass="four":teal(vom Elternteil übernommen)
Ein Aspekt von Custom-Properties, den die obigen Beispiele demonstrieren, ist, dass sie sich nicht genau wie Variablen in anderen Programmiersprachen verhalten. Der Wert wird dort berechnet, wo er benötigt wird, nicht gespeichert und in anderen Bereichen eines Stylesheets wiederverwendet. Zum Beispiel können Sie den Wert einer Eigenschaft nicht setzen und erwarten, dass Sie den Wert in der Regel eines Geschwisters der Nachkommen abrufen können. Die Eigenschaft wird nur für den übereinstimmenden Selektor und seine Nachkommen festgelegt.
Verwendung von @property zur Steuerung der Vererbung
Die @property Regel ermöglicht es Ihnen, explizit festzulegen, ob die Eigenschaft vererbt wird oder nicht.
Das folgende Beispiel erstellt eine Custom-Property mithilfe der @property Regel.
Die Vererbung ist deaktiviert, es ist ein <color> Datentyp definiert, und es gibt einen Anfangswert von teal.
Das Elternelement setzt --box-color auf einen Wert von green und nutzt --box-color als Wert für seine Hintergrundfarbe.
Das Kind-Element 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 doppelten Bindestrich-Syntax 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: teal;
}
.parent {
--box-color: green;
background-color: var(--box-color);
}
.child {
width: 80%;
height: 40%;
background-color: var(--box-color);
}
Da inherits: false; in der Regel gesetzt ist und ein Wert für die --box-color Eigenschaft nicht im .child-Bereich deklariert ist, wird der Anfangswert von teal 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 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.
Fallbacks in der var() Funktion definieren
Mit der var() Funktion können Sie mehrere Fallback-Werte definieren, wenn die gegebene 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. Zum 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 Einbeziehen einer Custom-Property als Fallback, wie im zweiten obenstehenden Beispiel (var(--my-var, var(--my-background, pink))), ist der richtige Weg, um mehr als einen Fallback mit var() bereitzustellen.
Sie sollten sich jedoch der Auswirkungen auf die Leistung dieser Methode bewusst sein, da es mehr Zeit braucht, durch die verschachtelten Variablen zu parsen.
Hinweis:
Die Syntax des Fallbacks erlaubt, wie die der Custom-Properties, Kommas. Beispielsweise 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 auch der initial-value, der in der @property Regel definiert ist, als Fallback-Mechanismus verwendet werden.
Dieses Konzept haben wir bereits im Abschnitt @property Vererbung gesehen.
Das folgende Beispiel setzt einen Anfangswert von --box-color auf teal mithilfe der @property Regel.
Im Regelwerk, das auf die Regel folgt, möchten wir --box-color auf pink setzen, aber es gibt einen Tippfehler im Wertnamen.
Gleiches gilt für das dritte <div>, in dem wir 2rem für die Custom-Property verwendet haben, die einen gültigen <color> Wert erwartet.
Sowohl 2rem als auch peenk sind ungültige Farbwerte, daher wird der Anfangswert von teal angewendet:
@property --box-color {
syntax: "<color>";
initial-value: teal;
inherits: false;
}
.one {
--box-color: pink;
background-color: var(--box-color);
}
.two {
--box-color: peenk;
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 betrachtet.
Wenn der Browser auf einen ungültigen Wert für eine reguläre CSS-Eigenschaft (z.B. einen Wert von 16px für die color Eigenschaft) stößt, verwirft er die Deklaration und Elemente erhalten die Werte, die sie hätten, wenn die Deklaration nicht existieren würde.
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 {
font-weight: bold;
color: blue;
}
p {
/* oops, not a valid color */
color: 16px;
}
Wenn jedoch die Werte von Custom-Properties analysiert werden, weiß der Browser noch nicht, wo sie verwendet werden, daher muss er fast alle Werte als gültig betrachten.
Leider können diese gültigen Werte mittels der var() funktionalen Notation in einem Kontext verwendet werden, in dem sie möglicherweise keinen Sinn ergeben.
Eigenschaften und benutzerdefinierte Variablen können zu ungültigen CSS-Deklarationen führen, was zum Konzept von gültig zur Berechnungszeit führt.
Wenn der Browser auf eine ungültige var() Substitution trifft, wird der Standard- oder geerbte Wert der Eigenschaft verwendet.
Dieses Beispiel ist wie das letzte, außer dass wir eine Custom-Property verwenden.
Der Browser ersetzt den Wert von --text-color anstelle von var(--text-color), aber 16px ist kein gültiger Eigenschaftswert für color.
Nach der Substitution ergibt die Eigenschaft keinen Sinn, sodass der Browser diese Situation in zwei Schritten behandelt:
- Überprüfen Sie, ob die Eigenschaft
colorvererbt werden kann. Das ist der Fall, aber dieses<p>hat kein übergeordnetes Element mit einer festgelegtencolorEigenschaft. Also gehen wir zum nächsten Schritt über. - Setzen Sie den Wert auf seinen Standard-Anfangswert, der schwarz ist.
<p>This paragraph is initially black.</p>
:root {
--text-color: 16px;
}
p {
font-weight: bold;
color: blue;
}
p {
color: var(--text-color);
}
Für solche Fälle kann die @property Regel unerwartete Ergebnisse verhindern, indem der Anfangswert der Eigenschaft festgelegt wird:
<p>This paragraph is initially black.</p>
@property --text-color {
syntax: "<color>";
inherits: false;
initial-value: teal;
}
:root {
--text-color: 16px;
}
p {
font-weight: bold;
color: blue;
}
p {
color: var(--text-color);
}
Werte in JavaScript
Um die Werte von Custom-Properties in JavaScript zu verwenden, ist es genau 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);