Theming mit CSS Custom Properties

"Ich roll' dann mal aus"  –  18 Kommentare

Die heise-Webentwicklung zeigt, wie man mit nativen CSS-Variablen Themes übersichtlich gestalten und dabei auch noch Code einsparen kann.

CSS Custom Properties ist die akurate Bezeichnung für das, was man landläufig CSS-Variablen nennt. Aus Präprozessoren wie Sass oder Less sind diese schon länger bekannt, nun haben sie ihren Weg auch ins native CSS gefunden. Wichtiger Unterschied – und da landet man wieder bei der akkuraten Bezeichnung – ist, dass native Variablen nicht beliebig im CSS eingesetzt werden können, beispielsweise um dynamisch Klassennamen zu erzeugen, sondern lediglich für die Eigenschaften (engl. property) eines Selektors.

Ein simples Beispiel, in dem die Variable mit dem Bezeichner --main-color definiert wird und im folgenden Code drei mal Verwendung findet:

:root {
--main-color: black;
}

p {
color: var(--main-color);
}

blockquote {
border-left: 2px solid var(--main-color);
}

.box {
background-color: var(--main-color);
}

Um ein Layout konstant zu halten, ist es hilfreich, Definitionen wie Schriftschnitte, Farben oder Abstände an einer Stelle zu definieren und dann nur eine Referenz darauf zu verwenden. Im Prinzip werden also häufig eher Variablen wie Konstanten genutzt. Anders jedoch beim Theming.

Themes im Web

Hier wird ein kleines Element der Beitragsseite per Theming angepasst.

Gestaltet man ein UI-Element, wird ihm in der Regel ein Grundlayout zugewiesen. Im Falle von heise online sind das oft unterschiedliche Graustufen. Wird dieses Element im Kontext einer anderen Marke verwendet, so bekommt es ein Color Branding – ein Theme.

Bei der iX-Startseite werden alle Elemente mit iX-Branding versehen. Eine andere Klasse lässt die Bühne im Rot von Make erscheinen.

Theming früher

Theming mit Präprozessoren wie Sass oder Less unter Zuhilfenahme von Mixins ist zwar für Entwickler angenehm, aber User müssen den Code für das Standardlayout ausgeliefert bekommen und dann noch die Regeln für das Color Branding, in dem die Farben überschrieben werden. Passiert das häufiger mit mehr Elementen und mehrfachem Color Branding, kommt ganz schön viel Code zusammen.

.std-layout {
color: #111;
background-color: #f0f0f0;
font-size: 1.2em;
line-height: 1.4;
width: 100%;
max-width: 400px;
padding: 5px;
border: 1px solid #999;
margin: 0 0 20px;
}

.std-layout--branding {
color: red;
background-color: white;
border-color: black;
}

Theming mit CSS Custom Properties

Beim Theming mit CSS Custom Properties werden nicht die Selektoren nochmal geschrieben, sondern lediglich den Variablen neue Werte zugewiesen. Im folgenden Beispiel sieht man auch wie das CSS-Theming dazu genutzt werden kann, deutlich zu machen, welche Teile eines Elements dazu gedacht sind per Theme angepasst zu werden (hier Farben) und welche nicht (beispielsweise die Schriftgröße).

Das kann hilfreich sein, wenn an einem UI-System im größeren Team gearbeitet wird, in dem die CSS-erschaffende Person nicht zwingend auch dieselbe ist, die das CSS später einsetzt. Das könnte zwar auch in einer ordentlichen Doku stehen, aber wer hat nicht schon mal in Projekten gesessen, in denen es "Doku" gab, die ihren Namen nicht wert war oder lediglich noch den historischen Initialzustand des Projekts abbildete?

// CSS
.theme {
--theme-primary: #111;
--theme-secondary: #f0f0f0;
--theme-tertiary: #999;
}

.theme--variant {
--theme-primary: red;
--theme-secondary: white;
--theme-tertiary: black;
}

.box {
color: var(--theme-primary);
background-color: var(--theme-secondary);
font-size: 1.2em;
line-height: 1.4;
width: 100%;
max-width: 400px;
padding: 5px;
border: 1px solid var(--theme-tertiary);
margin: 0 0 20px;
}

// HTML
<div class="box theme theme--variant">
...
</div>
C wie Kaskade

Innerhalb einer Seite kann man sich die Kaskade von CSS zu Nutze machen und mehrere Themes mischen. So kann eine Seite auf dem <body>-Tag beispielsweise die Klasse für das Theming A tragen, darin ist ein Artikel enthalten, der Theming B bekommt und selbst noch eine Querverweis-Box mit Theming C beinhaltet. Nach der Box greift wieder Theming B und nach dem Artikelende das Theming A.

<html>
<head>
<title>Theming</title>
</head>
<body class="theming theming--a">
<nav>
Navigation mit Theming A
</nav>

<article class="theming--b">
Ein Artikel mit Theming B

<section class="theming--c">
Querverweise mit Theming C
</section>

Es geht weiter mit Theming B
</article>

<footer>
Der Footer erhält wieder vom body vererbt das Theming A.
</footer>
</body>
</html>

Fallbacks

Can I Use zufolge können CSS Custom Properties aktuell auf gut 84 Prozent aller Systeme in Deutschland eingesetzt werden. Für alle anderen schaffen Fallbacks Abhilfe. Versteht ein Browser CSS Custom Properties überhaupt nicht, kann zuvor noch ein fester Wert definiert werden, der von der CSS Custom Property bei Browserverständnis einfach überschrieben wird.

.box {
color: #111;
color: var(--theme-primary);
}

Versteht ein Browser nun also var(--theme-primary) nicht, fällt er einfach auf color: #111; zurück.

Es gibt auch noch einen Fallback, falls aus irgendeinem Grund die definierte Variable selbst nicht vorhanden ist. Sollte im obigen Beispiel die Variable --theme-primary nicht definiert sein, dann lässt sich auch dafür ein Fallback angeben:

.box {
color: #111;
color: var(--theme-primary, #111);
}

CSS Custom Properties sind ein schönes Mittel, das CSS dynamisch zu halten, nicht zuletzt, weil die Variablen auch beim User per JavaScript jederzeit live verändert werden können. Sogar Shadow-DOM-Komponenten können mit einem Theme versehen werden, welche sich eigentlich per Definition nicht durch umgebendes CSS beeinflussen lassen. Dadurch ergeben sich interessante Möglichkeiten.

Außerdem helfen die CSS-Variablen, unnötigen Code an Stellen einzusparen, an denen man bisher zuvor gemachte Definitionen überschreiben musste. Variablen aus Präprozessoren können die Custom Properties nicht ersetzen, aber das tut ihrer Nützlichkeit keinen Abbruch. Die Verbreitung ist bereits recht gut und die einfachen Fallbacks ermöglichen schon heute den Einsatz dieser relativ jungen Technik.