Verwendung von CSS-Benutzereigenschaften (Variablen)
Benutzereigenschaften (manchmal als CSS-Variablen oder kaskadierende Variablen bezeichnet) sind von CSS-Autoren definierte Entitäten, die spezifische Werte darstellen, die in einem Dokument wiederverwendet werden sollen. Sie werden mit dem @property
-At-Regel oder durch Benutzereigenschafts-Syntax (z.B. --primary-color: blue;
) festgelegt. Benutzereigenschaften werden über die CSS-var()
-Funktion aufgerufen (z.B. color: var(--primary-color);
).
Komplexe Websites haben sehr große Mengen an CSS, was oft zu vielen wiederholten CSS-Werten führt. Beispielsweise ist es üblich, dieselbe Farbe an Hunderten von verschiedenen Stellen in Stylesheets zu sehen. Eine Farbe zu ändern, die an vielen Stellen dupliziert wurde, erfordert eine Suche und das Ersetzen in allen Regeln und CSS-Dateien. Benutzereigenschaften ermöglichen es, einen Wert an einer Stelle zu definieren und dann an mehreren anderen Stellen zu referenzieren, was die Handhabung erleichtert. Ein weiterer Vorteil ist die Lesbarkeit und Semantik. Beispielsweise ist --main-text-color
leichter zu verstehen als die hexadezimale Farbe #00ff00
, besonders wenn die Farbe in unterschiedlichen Kontexten verwendet wird.
Benutzereigenschaften, die mit zwei Bindestrichen (--
) definiert werden, unterliegen der Kaskade und erben ihren Wert von ihrem Elternteil.
Das @property
-At-Regel bietet mehr Kontrolle über die Benutzereigenschaft und erlaubt Ihnen zu spezifizieren, ob sie ihren Wert von einem Elternteil erbt, was der Initialwert ist 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 eines Elements verwenden.
Sie können var()
nicht für Eigenschaftsnamen, Selektoren oder anderes als Eigenschaftswerte verwenden, was bedeutet, dass Sie sie nicht in einer Media Query oder Container Query verwenden können.
Deklarieren von Benutzereigenschaften
In CSS können Sie eine Benutzereigenschaft mit zwei Bindestrichen als Präfix für den Eigenschaftsnamen oder mit der @property
-At-Regel deklarieren.
Die folgenden Abschnitte beschreiben, wie Sie diese beiden Methoden verwenden können.
Verwendung eines Präfixes mit zwei Bindestrichen (--
)
Eine Benutzereigenschaft mit dem Präfix von zwei Bindestrichen 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 Benutzereigenschaft --main-bg-color
erstellt wird und wie ein <named-color>
-Wert von brown
verwendet wird:
section {
--main-bg-color: brown;
}
Der dem Regelset gegebene Selektor (<section>
-Elemente im obigen Beispiel) definiert den Bereich, in dem die Benutzereigenschaft verwendet werden kann.
Aus diesem Grund ist es gängige Praxis, Benutzereigenschaften auf der :root
-Pseudoklasse zu definieren, sodass sie global referenziert werden können:
:root {
--main-bg-color: brown;
}
Dies muss nicht immer der Fall sein: Sie haben möglicherweise einen guten Grund, den Umfang Ihrer Benutzereigenschaften zu begrenzen.
Hinweis:
Benutzereigenschaftsnamen sind case-sensitiv — --my-color
wird als eine andere Benutzereigenschaft als --My-color
behandelt.
Verwendung des @property
-At-Regels
Das @property
-At-Regel ermöglicht es Ihnen, bei der Definition einer Benutzereigenschaft ausdrucksstärker zu sein, indem Sie eine Typ-Zuordnung mit der Eigenschaft verknüpfen, Standardwerte festlegen und die Vererbung steuern können.
Das folgende Beispiel erstellt eine Benutzereigenschaft namens --logo-color
, die ein <color>
erwartet:
@property --logo-color {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
Wenn Sie Benutzereigenschaften in JavaScript anstelle von direkt in CSS definieren oder verwenden möchten, gibt es eine entsprechende API zu diesem Zweck. Sie können in der Seite über CSS Properties and Values API nachlesen, wie dies funktioniert.
Referenzierung von Benutzereigenschaften mit var()
Unabhängig davon, welche Methode Sie wählen, um eine Benutzereigenschaft zu definieren, 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 Benutzereigenschaften
Lasst uns mit etwas HTML beginnen, dem wir einige Stile zuweisen möchten.
Es gibt ein <div>
, das als Container dient und einige Kindelemente 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 ein paar verschiedene Elemente basierend auf ihren Klassen zu stylen (einige Layoutregeln werden unten nicht gezeigt, damit wir uns auf die Farben konzentrieren können).
Je nach ihrer Klasse geben wir den Elementen cornflowerblue
oder aquamarine
Hintergrundfarben:
/* 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 erzeugt das folgende Ergebnis:
Es gibt die Möglichkeit, Benutzereigenschaften zu nutzen, um wiederkehrende Werte über diese Regeln hinweg zu ersetzen.
Nachdem --main-bg-color
im .container
-Bereich definiert wurde und der Wert an mehreren Stellen referenziert wird, 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, dies höher in der Kaskade zu deklarieren und die CSS-Vererbung das Problem lösen zu lassen. Für nicht triviale Projekte ist dies nicht immer möglich. Durch das Deklarieren einer Benutzereigenschaft auf der :root
-Pseudoklasse und deren Verwendung, wo sie im Dokument benötigt wird, kann ein CSS-Autor die Notwendigkeit der Wiederholung reduzieren:
/* 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 das vorherige Beispiel, ermöglicht jedoch eine kanonische Deklaration des gewünschten Eigenschaftswertes (--main-bg-color: cornflowerblue;
), was sehr nützlich ist, wenn Sie den Wert später im gesamten Projekt ändern möchten.
Vererbung von Benutzereigenschaften
Eine Benutzereigenschaft, die mit zwei Bindestrichen --
statt @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)
je nach Vererbung sind wie folgt:
class="one"
: ungültiger Wert, was der Standardwert einer so definierten Benutzereigenschaft istclass="two"
:cornflowerblue
class="three"
:aquamarine
class="four"
:cornflowerblue
(geerbt von seinem Elternteil)
Ein Aspekt von Benutzereigenschaften, 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. Zum Beispiel können Sie nicht den Wert einer Eigenschaft setzen und erwarten, den Wert in einer Regel eines Geschwisters oder Nachkommen abzurufen. Die Eigenschaft wird nur für den passenden Selektor und dessen Nachkommen festgelegt.
Verwendung von @property
zur Steuerung der Vererbung
Das @property
-At-Regel ermöglicht es Ihnen, explizit festzulegen, ob die Eigenschaft vererbt wird oder nicht.
Das folgende Beispiel erstellt eine Benutzereigenschaft mit dem @property
-At-Regel.
Die Vererbung ist deaktiviert, ein <color>
Datentyp ist definiert, und ein Initialwert 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 Kind-Element verwendet ebenfalls background-color: var(--box-color)
, und wir würden erwarten, dass es die Farbe green
hat, wenn Vererbung aktiviert wäre (oder wenn es mit der Doppelstrich-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: 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 festgelegt ist und ein Wert für die --box-color
Eigenschaft nicht innerhalb des .child
-Bereichs deklariert ist, wird der Initialwert von cornflowerblue
verwendet, anstelle des von dem Elternteil geerbten green
:
Fallback-Werte für Benutzereigenschaften
Sie können Fallback-Werte für Benutzereigenschaften mittels 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-Benutzereigenschaften nicht unterstützt werden, da der Fallback-Wert in diesem Fall nicht hilft. Fallbacks behandeln den Fall, in dem der Browser CSS-Benutzereigenschaften 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.
Definieren von Fallbacks in der var()
-Funktion
Mit 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 Benutzereigenschaft. Das zweite Argument der Funktion ist ein optionaler Fallback-Wert, der als Ersatzwert verwendet wird, wenn die referenzierte Benutzereigenschaft ungültig ist. Die Funktion akzeptiert zwei Parameter, wobei alles nach dem ersten Komma als zweiter Parameter zugewiesen 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);
}
Die Einbeziehung einer Benutzereigenschaft als Fallback, wie im zweiten obigen Beispiel (var(--my-var, var(--my-background, pink))
) zu sehen, ist der richtige Weg, um mehr als einen Fallback mit var()
bereitzustellen.
Sie sollten sich jedoch der Leistungsfolgen dieser Methode bewusst sein, da es mehr Zeit benötigt, um die verschachtelten Variablen zu parsen.
Hinweis:
Die Syntax des Fallbacks erlaubt Kommas, wie die der Benutzereigenschaften. 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 unter Verwendung des @property
Initialwerts
Abgesehen von der Verwendung von var()
kann der in der @property
-At-Regel definierte initial-value
als Fallback-Mechanismus verwendet werden.
In der Tat haben wir dies bereits im Abschnitt @property
Vererbung gesehen.
Das folgende Beispiel legt einen Initialwert von --box-color
auf cornflowerblue
mit dem @property
-At-Regel fest.
Im Regelset nach dem At-Regel 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 Benutzereigenschaft verwendet haben, die einen gültigen <color>
Wert erwartet.
Sowohl 2rem
als auch aqumarine
sind ungültige Farbwerte, daher wird der Initialwert 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 Benutzereigenschaften
Jede CSS-Eigenschaft kann einem definierten Satz von Werten zugewiesen werden. Wenn Sie versuchen, einer Eigenschaft einen Wert zuzuweisen, der außerhalb ihrer Menge gültiger Werte liegt, wird sie als ungültig betrachtet.
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) entdeckt, verwirft er die Deklaration, und den Elementen werden die Werte zugewiesen, 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 Regel color: blue
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 Benutzereigenschaften analysiert werden, weiß der Browser noch nicht, wo sie verwendet werden, daher muss er nahezu alle Werte als gültig betrachten.
Leider können diese gültigen Werte über die var()
funktionale Notation in einem Kontext verwendet werden, in dem sie möglicherweise keinen Sinn ergeben.
Eigenschaften und benutzerdefinierte Variablen können zu ungültigen CSS-Anweisungen führen, die zum Konzept von gültig zur Berechnungszeit führen.
Wenn der Browser auf eine ungültige var()
Substitution trifft, wird der initiale oder geerbte Wert der Eigenschaft verwendet.
Dieses Beispiel ist das gleiche wie das letzte, außer dass wir eine Benutzereigenschaft 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 macht die Eigenschaft keinen Sinn, sodass der Browser diese Situation in zwei Schritten handhabt:
- Prüfen Sie, ob die Eigenschaft
color
vererbbar ist. Sie ist es, aber dieses<p>
hat keinen Elternteil mit gesetztercolor
Eigenschaft. Also gehen wir zum nächsten Schritt. - Setzen Sie den Wert auf seinen standardmäßigen Initialwert, 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 der initiale Wert der Eigenschaft festgelegt wird:
<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 Benutzereigenschaften 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);