Verwendung von CSS-Benutzereigenschaften (Variablen)

Benutzereigenschaften (manchmal auch als CSS-Variablen oder kaskadierende Variablen bezeichnet) sind Entitäten, die von CSS-Autoren definiert werden und spezifische Werte repräsentieren, die in einem Dokument wiederverwendet werden können. Sie werden mit der @property At-Regel oder durch Benutzereigenschaftssyntax (z.B. --primary-color: blue;) gesetzt. Benutzereigenschaften werden mit der CSS-Funktion var() (z.B. color: var(--primary-color);) aufgerufen.

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, die an vielen Stellen dupliziert wurde, zu ändern, erfordert ein Suchen und Ersetzen über alle Regeln und CSS-Dateien hinweg. Benutzereigenschaften ermöglichen es, einen Wert an einer Stelle zu definieren und dann an mehreren anderen Stellen zu referenzieren, sodass das Arbeiten damit erleichtert wird. 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 verschiedenen Kontexten verwendet wird.

Benutzereigenschaften, die unter Verwendung von zwei Bindestrichen (--) definiert werden, unterliegen der Kaskade und erben ihren Wert von ihrem Elternelement. Die @property At-Regel ermöglicht eine genauere Steuerung der Benutzereigenschaft und lässt Sie festlegen, ob sie ihren Wert von einem Elternelement erbt, was der anfängliche Wert ist und welche Typbeschränkungen gelten sollten.

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 irgendetwas anderes außer Eigenschaftswerten verwenden, was bedeutet, dass Sie es nicht in einer Media Query oder Container Query verwenden können.

Deklarieren von Benutzereigenschaften

In CSS können Sie eine Benutzereigenschaft deklarieren, indem Sie zwei Bindestriche als Präfix für den Eigenschaftsnamen verwenden oder durch die Verwendung der @property At-Regel. Die folgenden Abschnitte beschreiben, wie Sie diese beiden Methoden einsetzen können.

Verwendung eines Präfixes mit zwei Bindestrichen (--)

Eine Benutzereigenschaft, die mit zwei Bindestrichen beginnt, beginnt mit --, gefolgt vom Eigenschaftsnamen (z.B. --my-property) und einem Eigenschaftswert, der jeden gültigen CSS-Wert darstellen kann. Wie jede andere Eigenschaft wird dies innerhalb eines Regelsets geschrieben. Das folgende Beispiel zeigt, wie man eine Benutzereigenschaft --main-bg-color erstellt und einen <named-color> Wert von brown verwendet:

css
section {
  --main-bg-color: brown;
}

Der Selektor, der dem Regelset zugewiesen ist (z.B. <section> Elemente im obigen Beispiel), definiert den Bereich, in dem die Benutzereigenschaft verwendet werden kann. Aus diesem Grund ist es eine gängige Praxis, Benutzereigenschaften auf der :root Pseudoklasse zu definieren, damit sie global referenziert werden können:

css
:root {
  --main-bg-color: brown;
}

Das muss nicht immer der Fall sein: Sie haben möglicherweise einen guten Grund, den Bereich Ihrer Benutzereigenschaften zu begrenzen.

Hinweis: Benutzereigenschaftsnamen sind case-sensitive — --my-color wird als separate Benutzereigenschaft zu --My-color behandelt.

Verwendung der @property At-Regel

Die @property At-Regel ermöglicht es Ihnen, mit der Definition einer Benutzereigenschaft ausdrucksstärker zu sein, indem Sie die Möglichkeit haben, einen Typ mit der Eigenschaft zu assoziieren, Standardwerte festzulegen und die Vererbung zu steuern. Das folgende Beispiel erstellt eine Benutzereigenschaft namens --logo-color, die eine <color> erwartet:

css
@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 darüber, wie dies funktioniert, auf der Seite CSS Properties and Values API lesen.

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:

css
details {
  background-color: var(--main-bg-color);
}

Erste Schritte mit Benutzereigenschaften

Beginnen wir mit etwas HTML, das wir mit einigen Stilen versehen möchten. Es gibt ein <div>, das als Container fungiert und einige Kindelemente enthält, einige davon mit verschachtelten Elementen:

html
<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 verschiedene Elemente basierend auf ihren Klassen zu gestalten (einige Layoutregeln werden unten nicht gezeigt, damit wir uns auf die Farben konzentrieren können). Je nach ihren Klassen geben wir Elementen Hintergrundfarben in cornflowerblue oder aquamarine:

css
/* 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;
}

Das ergibt folgendes Ergebnis:

Es besteht die Möglichkeit, Benutzereigenschaften zu verwenden, um sich wiederholende Werte in diesen Regeln zu ersetzen. Nachdem --main-bg-color im .container-Bereich definiert und sein Wert an mehreren Stellen referenziert wurde, sehen die aktualisierten Stile so aus:

css
/* 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 weiter oben in der Kaskade zu deklarieren und die CSS-Vererbung dieses Problems lösen zu lassen. Bei nicht-trivialen Projekten ist dies jedoch nicht immer möglich. Durch die Deklaration einer Benutzereigenschaft auf der :root Pseudoklasse und durch ihre Verwendung, wo immer nötig, im gesamten Dokument, kann ein CSS-Autor die Notwendigkeit zur Wiederholung reduzieren:

css
/* 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);
}

Das führt zum selben Ergebnis wie das vorherige Beispiel, erlaubt aber 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 -- anstelle von @property definiert wird, erbt immer den Wert ihres Elternteils. Dies wird im folgenden Beispiel dargestellt:

html
<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>
css
div {
  background-color: var(--box-color);
}

.two {
  --box-color: cornflowerblue;
}

.three {
  --box-color: aquamarine;
}

Die Ergebnisse von var(--box-color) abhängend von der Vererbung sind wie folgt:

  • class="one": ungültiger Wert, welcher der Standardwert einer so definierten Benutzereigenschaft ist
  • class="two": cornflowerblue
  • class="three": aquamarine
  • class="four": cornflowerblue (vom Elternteil geerbt)

Ein Aspekt von Benutzereigenschaften, 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, und nicht gespeichert und in anderen Bereichen eines Stylesheets wiederverwendet. Zum Beispiel können Sie nicht den Wert einer Eigenschaft setzen und erwarten, den Wert in der Regel eines Geschwisterelements eines Nachfahren wiederzugewinnen. Die Eigenschaft wird nur für den passenden Selektor und seine Nachfahren festgesetzt.

Die 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 Benutzereigenschaft unter Verwendung der @property At-Regel. Die Vererbung wird deaktiviert, ein <color> Datentyp wird festgelegt und ein anfänglicher Wert von cornflowerblue wird gesetzt.

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 Doppelpunktsyntax definiert wäre).

html
<div class="parent">
  <p>Parent element</p>
  <div class="child">
    <p>Child element with inheritance disabled for --box-color.</p>
  </div>
</div>
css
@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 innerhalb des .child-Bereichs kein Wert für die Eigenschaft --box-color deklariert ist, wird der Initialwert cornflowerblue anstelle von green verwendet, der vom Elternteil vererbt worden wäre:

Fallback-Werte für Benutzereigenschaften

Sie können Fallback-Werte für Benutzereigenschaften unter Verwendung der var() Funktion und des initial-value der @property At-Regel definieren.

Hinweis: Fallback-Werte werden nicht zur Behebung von Kompatibilitätsproblemen verwendet, falls CSS-Benutzereigenschaften nicht unterstützt werden, da der Fallback-Wert in diesem Fall nicht helfen wird. Fallbacks decken den Fall ab, 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.

Definition von Fallbacks in der var() Funktion

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 man mit Custom Elements und Shadow DOM arbeitet.

Das erste Argument der Funktion ist der Name der Benutzereigenschaft. Das zweite Argument der Funktion ist ein optionaler Fallback-Wert, der als Substitutionswert 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:

css
.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);
}

Einen Fallback für Benutzereigenschaften wie im zweiten Beispiel oben (var(--my-var, var(--my-background, pink))) zu inkludieren, ist die korrekte Weise, mehr als einen Fallback mit var() bereitzustellen. Sie sollten sich jedoch der Leistungsauswirkungen dieser Methode bewusst sein, da es mehr Zeit benötigt, um durch die verschachtelten Variablen zu parsen.

Hinweis: Die Syntax des Fallbacks, wie die von Benutzereigenschaften, erlaubt Kommata. 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 Initialwert

Abgesehen von der Verwendung von var() kann der initial-value, der 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 Initialwert von --box-color auf cornflowerblue unter Verwendung der @property At-Regel. Im Regelset, das der At-Regel folgt, wollen 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, so dass der Initialwert cornflowerblue angewendet wird:

css
@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 eine definierte Gruppe von Werten zugewiesen bekommen. Wenn Sie versuchen, einer Eigenschaft einen Wert zuzuweisen, der außerhalb dieser Gruppe gültiger Werte liegt, wird sie als ungültig betrachtet.

Wenn dem Browser ein ungültiger Wert für eine reguläre CSS-Eigenschaft begegnet (zum Beispiel ein Wert von 16px für die color Eigenschaft), verwirft er die Deklaration, und die Elemente erhalten die Werte, 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:

html
<p>This paragraph is initially black.</p>
css
p {
  color: blue;
}

p {
  /* oops, not a valid color */
  color: 16px;
}

Wenn die Werte von Benutzereigenschaften jedoch analysiert werden, weiß der Browser noch nicht, wo sie verwendet werden, daher müssen fast alle Werte als gültig betrachtet werden. Leider können diese gültigen Werte über die var() Funktionsnotation 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 berechneten Zeit führen.

Wenn der Browser auf eine ungültige var()-Ersetzung trifft, wird dann der initiale oder geerbte Wert der Eigenschaft verwendet. Dieses Beispiel ist genauso wie das letzte, außer dass wir eine benutzerdefinierte Eigenschaft 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 Ersetzung ergibt die Eigenschaft keinen Sinn, daher handelt der Browser diese Situation in zwei Schritten ab:

  1. Überprüfen Sie, ob die Eigenschaft color vererbbar ist. Sie ist, aber dieses <p> hat kein übergeordnetes Element mit der festgelegten color Eigenschaft. Also gehen wir zum nächsten Schritt über.
  2. Setzen Sie den Wert auf seinen standardmäßigen Anfangswert, der schwarz ist.
html
<p>This paragraph is initially black.</p>
css
: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:

html
<p>This paragraph is initially black.</p>
css
@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 genauso wie bei Standard-Eigenschaften.

js
// 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);

Siehe auch