Custom Properties

CSS Custom Properties (auch CSS-Variablen genannt) speichern Werte unter einem selbstgewählten Namen. Dadurch können Farben, Abstände, Schriftgrössen oder andere Werte zentral definiert und im gesamten Stylesheet wiederverwendet werden.

Im Gegensatz zu Sass- oder Less-Variablen sind Custom Properties live im Browser vorhanden. Sie können sich per Media Query, Klasse oder JavaScript zur Laufzeit ändern, ohne dass das Stylesheet neu kompiliert werden muss.


Syntax

Custom Properties werden mit zwei Bindestrichen (--) definiert und mit var() verwendet.

  • --nameDefiniert eine Custom Property.
  • var()Verwendet den Wert einer Custom Property.
:root {
    --main-color: rebeccapurple;
}

.element {
    color: var(--main-color);
}

Wichtig: Custom Properties sind case-sensitive. --Main-Color und --main-color sind zwei unterschiedliche Variablen.


Beispiel

Variablen definieren

:root {
    --primary: rebeccapurple;
    --spacing: 20px;
    --radius: 8px;
}

Variablen verwenden

.button {
    background: var(--primary);
    padding: var(--spacing);
    border-radius: var(--radius);
}

Scope: Global und lokal

Custom Properties werden häufig auf :root definiert und gelten dann global für das gesamte Dokument. Sie können aber auch lokal auf einzelnen Elementen definiert werden und gelten dann nur für dieses Element und seine Nachfahren.

Erbt --accent von :root
Überschreibt --accent lokal
:root {
    --accent: rebeccapurple;
}

.card {
    border: 4px solid var(--accent);
}

/* Lokale Überschreibung – gilt nur innerhalb von .local */
.card.local {
    --accent: coral;
}

Custom Properties vererben sich wie normale CSS-Properties an Kindelemente – eine lokale Neudefinition wirkt sich nur auf das Element selbst und seine Nachfahren aus.


Fallback-Werte

var() kann einen zweiten Parameter (Fallback-Wert) erhalten. Dieser wird verwendet, wenn die Custom Property nicht definiert ist.

--missing-color ist nicht definiert
.element {
    background: var(--missing-color, limegreen);
    /* limegreen wird verwendet, weil --missing-color nirgends existiert */
}

Fallbacks können auch verschachtelt werden. Erst wenn keine der angegebenen Custom Properties existiert, wird der feste Wert verwendet: var(--a, var(--b, red)).


Live Theming – ohne JavaScript

Weil Custom Properties zur Laufzeit ausgewertet werden, reicht eine Checkbox mit :has(), um ein ganzes Farbschema umzuschalten.

Beispiel-Karte

Hintergrund, Text und Rahmenfarbe kommen alle aus Custom Properties.

<div class="theme">
    <label>
        <input type="checkbox" id="theme-toggle">
        Dark Mode
    </label>

    <div class="card">
        <h4>Beispiel-Karte</h4>
        <p>Hintergrund, Text und Rahmenfarbe kommen alle aus Custom Properties.</p>
    </div>
</div>
.theme {
    --bg: #fff;
    --text: #222;
    --accent: rebeccapurple;
}

.theme:has(#theme-toggle:checked) {
    --bg: #222;
    --text: #fff;
    --accent: coral;
}

.card {
    background: var(--bg);
    color: var(--text);
    border: 3px solid var(--accent);
    padding: 20px;
    transition: background .3s, color .3s, border-color .3s;
}

Skalen aufbauen

Custom Properties eignen sich ideal für einheitliche Abstands- oder Grössensysteme. Die Werte werden zentral definiert und im gesamten Stylesheet wiederverwendet.

--space-sm
--space-md
--space-lg
:root {
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 32px;
}

.card {
    padding: var(--space-md);
    gap: var(--space-sm);
}

Kombination mit calc()

Custom Properties und calc() lassen sich ideal kombinieren. Dadurch entstehen flexible und leicht wartbare Layouts.

:root {
    --sidebar-width: 250px;
    --gap: 20px;
}

.content {
    width: calc(100% - var(--sidebar-width) - var(--gap));
}

Details zu calc() selbst findest du in der calc()-Lektion.


Responsive Custom Properties

Custom Properties können in Media Queries oder Container Queries neu definiert werden. Alle Stellen, die diese Variable verwenden, übernehmen den neuen Wert automatisch.

:root {
    --font-size-factor: 1;
}

h1 {
    font-size: calc(var(--font-size-factor) * 2.5rem);
}

@media screen and (min-width: 601px) {
    :root {
        --font-size-factor: 1.2;
    }
}

@media screen and (min-width: 901px) {
    :root {
        --font-size-factor: 1.5;
    }
}

@property

Mit @property lassen sich Custom Properties typisieren sowie mit einem Startwert und Vererbungsverhalten versehen. Dadurch können sie animiert werden, weil der Browser ihren Datentyp kennt.

  • syntaxLegt den Datentyp der Custom Property fest, z. B. <color>, <length>, <angle> oder <number>.
  • inheritsLegt fest, ob die Custom Property vererbt wird.
  • initial-valueDefiniert den Standardwert der Custom Property.
@property --angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

.element {
    transition: --angle 0.3s;
    background: conic-gradient(from var(--angle), red, blue);
}

See the Pen @property Demo by Intensivstation (@intensivstation) on CodePen.

Hinweis: @property wird von aktuellen Browsern unterstützt. Für ältere Browser sollte eine Fallback-Strategie vorgesehen werden.


JavaScript & Custom Properties

Custom Properties können zur Laufzeit per JavaScript gelesen und geändert werden. Das eignet sich beispielsweise für Theme-Switcher oder interaktive Benutzeroberflächen.

// Wert setzen
document.documentElement.style.setProperty('--accent', 'coral');

// Wert auslesen
const value = getComputedStyle(document.documentElement)
    .getPropertyValue('--accent');

CSS- vs. Sass-Variablen

  • Custom PropertiesBleiben im Browser erhalten und können sich zur Laufzeit ändern.
  • Sass-Variablen ($name)Werden beim Kompilieren ersetzt und existieren im Browser nicht mehr.

Beide Systeme haben ihre Stärken. Sass-Variablen werden beim Kompilieren ersetzt und eignen sich für feste Werte. Custom Properties bleiben im Browser erhalten und können sich zur Laufzeit ändern.


Cheat Sheet

  • --name: wert;Definiert eine Custom Property.
  • var(--name)Verwendet den Wert einer Custom Property.
  • var(--name, fallback)Verwendet einen Fallback-Wert, falls die Property nicht definiert ist.
  • :rootDefiniert global gültige Custom Properties.
  • @propertyErstellt typisierte und animierbare Custom Properties.
  • syntaxLegt den Datentyp der Custom Property fest.
  • inheritsLegt fest, ob die Property vererbt wird.
  • initial-valueDefiniert den Standardwert.

Kurz gesagt

  • Custom Properties speichern Werte unter einem --name und werden mit var() verwendet.
  • Sie können global oder lokal definiert und zur Laufzeit geändert werden.
  • @property ermöglicht typisierte und animierbare Custom Properties.
  • Auf :root definierte Custom Properties gelten global, auf einzelnen Elementen nur lokal für das Element und seine Nachfahren.