Zum Inhalt springen
HTML & CSS Anfänger 25 min

CSS Custom Properties (Variablen)

Lerne CSS Custom Properties kennen: Variablen definieren, Themes erstellen und dynamische Styles mit modernem CSS.

Aktualisiert:

CSS Custom Properties

CSS Custom Properties (auch CSS-Variablen genannt) sind eine der maechtigsten Neuerungen in modernem CSS. Sie ermoeglichen dir, Werte zentral zu definieren und ueberall wiederzuverwenden — und das Beste: Sie sind dynamisch und koennen zur Laufzeit geaendert werden.

Grundsyntax

Variablen definieren

Variablen beginnen immer mit zwei Bindestrichen (--):

:root {
    --primary-color: #e44d26;
    --secondary-color: #264de4;
    --text-color: #333333;
    --bg-color: #ffffff;
    --border-radius: 8px;
    --spacing: 1rem;
}

:root bedeutet, dass die Variable global verfuegbar ist.

Variablen verwenden

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

h1 {
    color: var(--primary-color);
}

a {
    color: var(--secondary-color);
}

Fallback-Werte

.element {
    /* Wenn --accent nicht definiert ist, verwende #e44d26 */
    color: var(--accent, #e44d26);

    /* Verschachtelte Fallbacks */
    background: var(--bg-custom, var(--bg-color, white));
}

Warum Custom Properties?

Vorher: Werte ueberall verstreut

/* Ohne Variablen: Farbe an 20 Stellen aendern */
.header { background: #e44d26; }
.button { background: #e44d26; }
.link { color: #e44d26; }
.highlight { border-color: #e44d26; }
/* ... und so weiter */

Nachher: Eine Stelle aendern

:root {
    --brand: #e44d26;
}

.header { background: var(--brand); }
.button { background: var(--brand); }
.link { color: var(--brand); }
.highlight { border-color: var(--brand); }
/* Farbe aendern? Nur an einer Stelle! */

Ein komplettes Design-System

:root {
    /* Farben */
    --color-primary: #e44d26;
    --color-primary-light: #f0856e;
    --color-primary-dark: #c0392b;
    --color-secondary: #264de4;
    --color-success: #10b981;
    --color-warning: #f59e0b;
    --color-error: #ef4444;

    --color-text: #1a1a2e;
    --color-text-light: #4a5568;
    --color-bg: #ffffff;
    --color-bg-alt: #f8fafc;
    --color-border: #e2e8f0;

    /* Typografie */
    --font-heading: Georgia, serif;
    --font-body: system-ui, -apple-system, sans-serif;
    --font-mono: 'Fira Code', Consolas, monospace;

    /* Groessen */
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 2rem;
    --text-4xl: 2.5rem;

    /* Abstaende */
    --space-xs: 0.25rem;
    --space-sm: 0.5rem;
    --space-md: 1rem;
    --space-lg: 1.5rem;
    --space-xl: 2rem;
    --space-2xl: 3rem;
    --space-3xl: 5rem;

    /* Rahmen */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-full: 9999px;

    /* Schatten */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
    --shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.15);

    /* Transitions */
    --transition-fast: 150ms ease;
    --transition-normal: 300ms ease;
}

Verwendung:

body {
    font-family: var(--font-body);
    color: var(--color-text);
    background: var(--color-bg);
}

.card {
    padding: var(--space-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--transition-normal);
}

.card:hover {
    box-shadow: var(--shadow-lg);
}

.btn {
    background: var(--color-primary);
    color: white;
    padding: var(--space-sm) var(--space-lg);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
}

Dark Mode mit Custom Properties

/* Light Mode (Standard) */
:root {
    --color-bg: #ffffff;
    --color-bg-alt: #f8fafc;
    --color-text: #1a1a2e;
    --color-text-light: #4a5568;
    --color-border: #e2e8f0;
    --color-primary: #e44d26;
}

/* Dark Mode */
@media (prefers-color-scheme: dark) {
    :root {
        --color-bg: #0f172a;
        --color-bg-alt: #1e293b;
        --color-text: #e2e8f0;
        --color-text-light: #94a3b8;
        --color-border: #334155;
        --color-primary: #f59e0b;
    }
}

/* Die gleichen CSS-Regeln funktionieren fuer beide Modi! */
body {
    background: var(--color-bg);
    color: var(--color-text);
}

.card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
}

Manueller Theme-Wechsel

/* Theme-Klassen auf <html> oder <body> */
[data-theme="dark"] {
    --color-bg: #0f172a;
    --color-text: #e2e8f0;
    --color-primary: #f59e0b;
}

[data-theme="light"] {
    --color-bg: #ffffff;
    --color-text: #1a1a2e;
    --color-primary: #e44d26;
}
<html data-theme="light">

Scope: Lokale Variablen

Custom Properties koennen auch lokal definiert werden:

.card {
    --card-padding: 1.5rem;
    --card-bg: white;

    padding: var(--card-padding);
    background: var(--card-bg);
}

.card.compact {
    --card-padding: 0.75rem;
    /* Nur in .compact geaendert, Rest bleibt gleich */
}

.card.dark {
    --card-bg: #1a1a2e;
    color: white;
}

Komponenten-basierte Variablen

.btn {
    --btn-bg: var(--color-primary);
    --btn-color: white;
    --btn-padding: 0.5rem 1.5rem;
    --btn-radius: var(--radius-md);

    background: var(--btn-bg);
    color: var(--btn-color);
    padding: var(--btn-padding);
    border-radius: var(--btn-radius);
    border: none;
    cursor: pointer;
}

.btn-secondary {
    --btn-bg: transparent;
    --btn-color: var(--color-primary);
    border: 2px solid var(--color-primary);
}

.btn-success {
    --btn-bg: var(--color-success);
}

.btn-large {
    --btn-padding: 0.75rem 2.5rem;
    font-size: var(--text-lg);
}

Berechnungen mit calc()

Custom Properties funktionieren hervorragend mit calc():

:root {
    --base-size: 1rem;
    --columns: 3;
    --gap: 1.5rem;
}

.grid-item {
    width: calc((100% - (var(--columns) - 1) * var(--gap)) / var(--columns));
}

.dynamic-spacing {
    padding: calc(var(--base-size) * 2);
    margin-bottom: calc(var(--base-size) * 1.5);
}

Farben dynamisch mit color-mix()

:root {
    --brand: #e44d26;
}

.hover-light {
    background: color-mix(in srgb, var(--brand), white 20%);
}

.hover-dark {
    background: color-mix(in srgb, var(--brand), black 20%);
}

.transparent {
    background: color-mix(in srgb, var(--brand), transparent 50%);
}

Uebungen

Uebung 1: Design-System erstellen

Erstelle ein eigenes Design-System mit Custom Properties fuer:

  • 5 Farben (Primary, Secondary, Success, Warning, Error)
  • 3 Schriftgroessen
  • 4 Abstandsgroessen
  • 2 Schattengroessen

Uebung 2: Dark Mode implementieren

Implementiere einen Dark Mode mit prefers-color-scheme. Verwende ausschliesslich Custom Properties fuer alle Farben, sodass der Wechsel nur die Variablenwerte aendert.

Uebung 3: Button-Varianten

Erstelle ein Button-System mit einer Basis-Klasse .btn und Varianten (.btn-primary, .btn-secondary, .btn-outline), die nur die lokalen Variablen ueberschreiben.

Was kommt als Naechstes?

Im naechsten Kapitel lernst du CSS Animationen und Transitions:

  • Sanfte Uebergaenge mit Transitions
  • Komplexe Animationen mit @keyframes
  • Performance-Tipps fuer Animationen

Zusammenfassung

  • Custom Properties werden mit --name definiert und mit var(--name) verwendet
  • :root macht Variablen global verfuegbar
  • Fallback-Werte mit var(--name, fallback) schuetzen vor fehlenden Variablen
  • Dark Mode wird durch Ueberschreiben der Variablen in @media (prefers-color-scheme: dark) einfach
  • Lokale Variablen in Komponenten ermoeglichen flexible Varianten
  • Custom Properties sind dynamisch — sie koennen mit JavaScript oder Media Queries geaendert werden
  • color-mix() erstellt Farbvariationen basierend auf Variablen

Pro-Tipp: Benenne deine Custom Properties nach ihrer Funktion, nicht nach ihrem Wert. Statt --blue verwende --color-primary, statt --20px verwende --space-md. So kannst du das Theme aendern, ohne alle Variablennamen umzubenennen!

Zurück zum HTML & CSS Kurs