Einführung in Custom Properties

In diesem Artikel möchte ich dir einen Einstieg in Custom Properties, auch bekannt als CSS Variablen geben. Wie funktionieren sie? Was sind die Vor- und Nachteile gegenüber Sass-Variablen? Und was musst du bei der Verwendung beachten?

Als ich mich das erste Mal mit Custom Properties beschäftigte, da schienen benutzerdefinierte Eigenschaften noch unendlich weit weg. Browser wie Chrome und Firefox unterstützten zwar schon Custom Properties, aber der generelle Browser-Support war noch nicht so gut, dass man sie bedenkenlos einsetzen konnte.

Mittlerweile liegt der Browser-Support bei etwa 92%, sodass ich mich dazu entschloss, diese auch in unserem neuen Contao Theme LASR zu verwenden. Aber was sind Custom Properties überhaupt?

Die Idee von Custom Properties

In meinem Buch Crashkurs Sass bin ich bereits auf die Vorteile von Variablen eingegangen:

Du definierst zu Beginn ein paar Variablen, zum Beispiel die Unternehmensfarbe, Schriftarten und Abstände und kannst im weiteren Verlauf dann mit diesen Variablen arbeiten. Wenn sich dann ein Wert ändert, musst du nur die Variable anpassen, anstatt den Wert in der kompletten SCSS/CSS-Datei zu suchen und zu ändern.

Vor der Entwicklung von Custom Properties war dies nur mithilfe eines Präprozessors wie LESS oder Sass möglich. Aber dank Custom Properties können wir Variablen nun auch nativ in CSS nutzen.

Ein Beispiel:

See the Pen yLBVWJe by Dennis Erdmann (@erdmannfreunde) on CodePen.


Die oben angegebene Variable, z.B. --color-brand wird ausgelesen und dem Link als Farbe zugewiesen. Du kannst es selbst mal testen, indem du das Beispiel nach Belieben anpasst.

2 Dinge sind allerdings wichtig zu beachten:

  1. Du bist zwar frei in der Benennung, aber Variablen müssen immer mit dem Doppelminus -- gekennzeichnet werden.
  2. Um Variablen auszuwerten, müssen diese von var( ) umschlossen werden.

Theoretisch könntest du also für jede Eigenschaft eine Variable definieren und auf diese im späteren Verlauf zugreifen. Praktisch muss man natürlich schauen, an welchen Stellen es sinnvoll ist, eine Variable zu deklarieren.

Für unser Nutshell Framework ab Version 1.0 haben wir große Teile der Sass-Variablen durch Custom Properties ersetzt. Damit nähern wir uns einerseits wieder mehr dem CSS-Standard an, andererseits können wir auf weitere Vorteile von Custom Properties zurückgreifen, die so bisher mit Sass-Variablen nicht möglich waren.  

Vorteile von Custom Properties

Custom Properties haben gegenüber Sass-Variablen einen entscheidenden Vorteil: Sie können zur Laufzeit angepasst werden.

Ein gutes Beispiel ist hier der von Apple beworbene Dark-Mode, also die Möglichkeit am Mac einzustellen, dass die Programme im dunklen Farbschema angezeigt werden. Mittlerweile unterstützt nicht nur Safari, sondern auch Chrome den Dark Mode, dass bedeutet, der Browser weiß, welchen Modus du eingestellt hast und kann die Einstellung an die Website übergeben.

Aber egal ob das Betriebssystem bzw. der Browser diesen Dark Mode unterstützt oder nicht. Wenn du eine Website um eine dunkle Variante oder einen Kontrast-Modus ergänzen wolltest, dann sah das in der Vergangenheit in etwa so aus: 

// normale Ansicht

body {
background-color: #F0F0F0;
color: #090727;
}

[id="wrapper"] {
background-color: #FFFFFF;
}



.ce_hero .content_container {
background-color: #FFFFFF;
}



// Dark Mode
body.dark {
background-color: #555555;
color: #DDDDDD;
}

.dark [id="wrapper"] {
background-color: #222222;
}



.dark .ce_hero .content_container {
background-color: #222222;
}

Für jede Klasse, die Farbanweisungen für eine helle Darstellung hatte, musstest du über eine zusätzliche Klasse, z.B. .dark den bestehenden Farbwert überschreiben. Per Javascript hast du dann die Klasse .dark hinzugefügt und die Eigenschaften wurden überschrieben.

Mit Custom Properties geht das nun deutlich einfacher, indem du einfach die Variablen überschreibst. Schauen wir uns das Beispiel oben noch einmal mit Custom Properties an:

// normale Ansicht
:root {
--color-page-background: #F0F0F0;
--color-text: #090727;
--wrapper-background: #FFFFFF;
--hero-background: #FFFFFF;
}

body {
background-color: var(--color-page-background);
color: var(--color-text);
}

[id="wrapper"] {
background-color: var(--wrapper-background);
}



.ce_hero .content_container {
background-color: var(--hero-background);
}



// Dark Mode
.dark {
--color-page-background: #555555;
--color-text: #DDDDDD;
--wrapper-background: #222222;
--hero-background: #222222;
}

 

Ziemlich einfach, oder? Mit Custom Properties kannst du dir ziemlich viel Schreibarbeit sparen und dabei deine CSS-Anweisungen schlanker und übersichtlicher halten. 

Vorteile für die Theme-Entwicklung

Die Tatsache, dass sich Custom Properties zur Laufzeit ändern lassen, hat für uns auch große Vorteile bei der Theme-Entwicklung bzw. bei der Theme-Demo. So planen wir, einen Theme-Konfigurator zu entwickeln, der die Anpassung von Farben, Schriften und Abständen in Echtzeit ermöglicht. Die Einstellungen ließen sich dann über den Konfigurator speichern und exportieren.

Nachteile von Custom Properties gegenüber Sass-Variablen

An machen Stellen merkt man dann aber doch, dass Custom Properties noch ein paar Funktionen fehlen, die man bei Sass-Variablen zu schätzen gelernt hat. Zum Beispiel wenn es um Berechnungen geht.

So kann ich in Sass Abstände generieren, indem ich einen Wert oder eine Variable mit einem Faktor multipliziere oder dividiere:

$base-spacing-unit: 1rem
$base-spacing-unit--lg: $base-spacing-unit * 2;

.ce_text {
margin-bottom: $base-spacing-unit--lg;
}

In der späteren CSS-Datei wird .ce_text ein margin-bottom: 2rem bekommen.

Mit Custom Properties können Werte nicht so einfach multipliziert werden. Stattdessen müssen wir hier mit der calc() Funktion arbeiten:

--base-spacing-unit: 1rem
--base-spacing-unit--lg: calc(var(--base-spacing-unit) * 2);

.ce_text {
margin-bottom: var(--base-spacing-unit--lg);
}

In der CSS-Datei werden die CSS-Variablen nicht aufgelöst, d.h. .ce_text wird weiterhin ein margin-bottom: var(--base-spacing-unit--lg) haben, was wiederum calc(var(--base-spacing-unit) * 2) entspricht, was wiederum calc(1rem * 2) entspricht.

Beim Debugging muss man also unter Umständen einer längeren Kette von Berechnungen folgen, bevor man weiß, wie dieser Wert zustande kam. Das muss nicht unbedingt schlecht sein, aber wenn man es bisher gewohnt war, im Web Inspektor Werte zu sehen, muss man sich hier erstmal umgewöhnen.

Das Problem mit der Browser-Unterstützung

Ein wesentlich größeres Problem ist der eingangs erwähnte Browser-Support von Custom-Properties. Dieser liegt zwar mittlerweile bei 92%, bedeutet aber auch, dass bei rund 8% der Nutzer die Website nicht korrekt dargestellt wird. Und das ist noch untertrieben. Wenn ich die Unternehmensfarbe über Custom Properties zuweise und diese nicht unterstützt wird, was passiert dann? Nun ja, dann wird im Zweifelsfall die Standard-Eigenschaft genutzt. Wenn ich Abstände über Custom Properties definiert habe und diese nicht unterstützt werden, dann wird in älteren Browsern kein Abstand zu sehen sein.

Das ist auch der Grund, warum das LASR-Theme offiziell erst ab MS Edge 18 funktioniert und in älteren Browsern ein Warnhinweis angezeigt wird. Damit das Layout nicht ganz wie Kraut und Rüben aussieht, haben wir das PostCSS-Plugin für Custom Properties verwendet.

Langfristig wäre es aber schön, wenn wir auf die Fallbacks komplett verzichten könnten, auch um die CSS-Datei(en) schlank zu halten.

Fazit zu Custom Properties

Während ich diesen Artikel schrieb sind mir viele weitere Stellen eingefallen, an denen wir das Nutshell Framework durch den Einsatz von Custom Properties weiter vereinfachen könnten. Aber auch für uns sind Custom Properties noch relativ neu und das Umdenken von Sass-Variablen zu Custom Properties dauert ein wenig.

Für weitere Informationen zu Custom Properties empfehle ich dir die Übersicht bei CSS Tricks. Hier findest du weitere Beispiele, wie du Variablen einsetzen kannst, welche Probleme bei der Verwendung auftauchen können und wie du sie lösen oder umgehen kannst.

Wenn du Custom Properties einmal in Aktion sehen möchtest, dann schau dir mal unsere Contao Themes genauer an. Ab LASR setzen wir auf CSS Variablen, um unsere Contao Themes zu individualisieren.