Machen Sie Ihr CSS mit benutzerdefinierten CSS-Eigenschaften dynamisch

Veröffentlicht: 2022-03-11

Wenn Sie schon eine Weile CSS schreiben, müssen Sie irgendwann das Bedürfnis nach Variablen verspürt haben. Benutzerdefinierte CSS-Eigenschaften ähneln in gewisser Weise der CSS-eigenen Implementierung von Variablen. Bei richtiger Verwendung können sie jedoch so viel mehr sein als nur Variablen.

Mit benutzerdefinierten CSS-Eigenschaften können Sie:

  • Weisen Sie einer Eigenschaft beliebige Werte mit einem Namen Ihrer Wahl zu
  • Verwenden Sie die Funktion var() , um diese Werte in anderen Eigenschaften zu verwenden

Obwohl die Unterstützung für benutzerdefinierte CSS-Eigenschaften im Moment ein etwas steiniger Weg ist und einige Browser sie unter Flags unterstützen, die zuvor aktiviert oder auf true gesetzt werden müssen, wird erwartet, dass ihre Unterstützung in Zukunft dramatisch zunehmen wird, daher ist es wichtig zu verstehen wie man sie nutzt und nutzt. 1

Verwenden von benutzerdefinierten CSS-Eigenschaften

In diesem Artikel erfahren Sie, wie Sie benutzerdefinierte CSS-Eigenschaften verwenden können, um Ihre Stylesheets etwas dynamischer zu gestalten, wodurch möglicherweise dieser zusätzliche Sass/LESS-Schritt in Ihrer Asset-Pipeline obsolet wird.

Die ursprüngliche und weniger leistungsstarke CSS-Variable

Bevor wir mit der Erörterung benutzerdefinierter CSS-Eigenschaften beginnen, sollte beachtet werden, dass CSS seit langem eine Art Variable hat, und das ist das Schlüsselwort currentColor . Diese selten verwendete, aber weit verbreitete Variable bezieht sich auf den aktuellen Farbwert eines Elements. Es kann für jede Deklaration verwendet werden, die einen color akzeptiert, und es lässt sich perfekt kaskadieren.

Schauen wir uns ein Beispiel an:

 .element { color: blue; border: 2px solid currentColor; /* Sets a solid, 2px wide, blue border to the element */ }

Dies kann neben der Kaskadierung auch Folgendes bewirken:

 .element span { background: currentColor; /* Sets a blue background color for every span child of .element, unless a color property is declared in this same block */ } .element span.red { color: red; /* Sets a red background color for every span child of .element that has the class .red, since currentColor is applied to the background of every span child of .element no matter if they have the .red class or not */ }

Abgesehen davon, dass es nicht als Variable per se in der Spezifikation enthalten war, besteht das Hauptproblem bei currentColor darin, dass es nur den Wert der color -Eigenschaft akzeptiert, was in einigen Fällen die Arbeit erschweren kann.

Vollwertige CSS-Variablen

Einer der Hauptvorteile der Verwendung von CSS-Prä-/Postprozessoren besteht darin, dass sie es ermöglichen, Werte in einem Schlüsselwort zu speichern und sie bei Bedarf einem bestimmten Selektor zuzuordnen.

Auf lange Nachfrage von Entwicklern hin wurde ein Entwurf für eine Interpretation nativer Variablen für CSS geschrieben. Diese werden formal als benutzerdefinierte CSS-Eigenschaften bezeichnet, werden aber manchmal auch als CSS-Variablen bezeichnet.

Die aktuelle Spezifikation für native benutzerdefinierte CSS-Eigenschaften deckt dieselben Verhaltensweisen wie Prä-/Postprozessorvariablen ab. Auf diese Weise können Sie Farbcodes, Größen mit allen bekannten Einheiten oder bei Bedarf nur ganze Zahlen speichern (z. B. wenn Sie denselben Divisor oder Multiplikator verwenden müssen).

Die Syntax für benutzerdefinierte CSS-Eigenschaften ist im Vergleich zu anderen Sprachen etwas seltsam, aber es macht sehr viel Sinn, wenn Sie ihre Syntax mit anderen Funktionen im selben CSS-Ökosystem vergleichen:

 :root { --color-black: #2e2e2e; } .element { background: var(--color-black); }

Jetzt denken Sie vielleicht: „Was ist das denn für eine Syntax!?“

Nun, Lea Verou erklärt den Grund für diese „Strich-Strich“-Syntax mit absoluter Einfachheit, wie sie in ihrem erstaunlichen Vortrag CSS-Variablen sagt: var(–subtitle):

Sie funktionieren genauso wie jede andere CSS-Eigenschaft […]. So viele Leute fragen mich, warum wir kein Dollar [Zeichen] oder ähnliches verwendet haben, und der Grund, warum wir kein Dollar [Zeichen] verwendet haben, ist, dass wir möchten, dass die Leute sowohl SASS als auch Präprozessorvariablen und verwenden können CSS-Variablen. Sie sind beide unterschiedliche Dinge, sie erreichen unterschiedliche Ziele, es gibt Dinge, die Sie mit CSS-Variablen tun können, die Sie absolut nicht mit SASS tun können, und es gibt Dinge, die Sie mit SASS-Variablen tun können, die Sie mit CSS-Variablen nicht tun können, also wollen wir Leute beide in demselben Stylesheet verwenden können, also können Sie sich die Dash-Dash-Syntax wie eine Präfix-Eigenschaft mit einem leeren Präfix vorstellen.

Wir können den Wert der benutzerdefinierten Eigenschaft mit der Funktion var() abrufen, die wir überall verwenden können, außer für Selektoren, Eigenschaftsnamen oder Deklarationen von Medienabfragen.

Es ist erwähnenswert, dass Prä-/Postprozessor-Variablen zwar nur zur Kompilierzeit verwendet werden, CSS-Variablen jedoch dynamisch verwendet und aktualisiert werden können. Was bedeutet das? Das bedeutet, dass sie im eigentlichen CSS-Stylesheet erhalten bleiben. Die Vorstellung, dass es sich um Variablen handelt, bleibt also auch nach dem Kompilieren der Stylesheets bestehen.

Um es deutlicher zu machen, lassen Sie mich die Situation anhand einiger Beispiele veranschaulichen. Der folgende Codeblock ist Teil eines SASS-Stylesheets:

 :root { $value: 30px; } @media screen and (min-width: 768px) { $value: 60px; } .corners { border-radius: $value; }

Dieses Snippet von SASS-Deklarationen und -Regeln wird wie folgt in CSS kompiliert:

 .corners { border-radius: 30px; }

Sie können sehen, dass sowohl die Eigenschaften in :root als auch die media nach der Kompilierung verloren gehen, da SASS-Variablen nicht in einer CSS-Datei existieren können (oder genauer gesagt, sie können gezwungen werden, in einer CSS-Datei zu existieren, aber ignoriert werden da ein Teil ihrer Syntax ungültiges CSS ist), sodass der Wert der Variablen anschließend nicht aktualisiert werden kann.

Betrachten wir nun den gleichen Fall, aber angewendet nur unter Verwendung von CSS-Variablen ohne angewendeten CSS-Prä-/Postprozessor (dh ohne dass keine Transpilation oder Kompilierung durchgeführt wird):

 :root { --value: 30px; } @media screen and (min-width: 768px) { --value: 60px; } .corners { border-radius: var(--value); }

Offensichtlich ändert sich nichts, da wir nichts kompiliert/transpiliert haben, und der Wert der benutzerdefinierten Eigenschaft kann dynamisch aktualisiert werden. Wenn wir also beispielsweise den Wert von --value mit etwas wie JavaScript ändern, wird der Wert in jeder Instanz aktualisiert, in der er mit der Funktion var() aufgerufen wird.

Die Möglichkeiten benutzerdefinierter Eigenschaften machen diese Funktion so leistungsfähig, dass Sie sogar Dinge wie die automatische Präfixierung durchführen können.

Lea Verou geht mit der Eigenschaft clip-path vorbildlich vor. Wir beginnen damit, den Wert der Eigenschaft, der wir ein Präfix voranstellen möchten, auf initial zu setzen, aber eine benutzerdefinierte Eigenschaft zu verwenden, und fahren dann damit fort, den Wert jeder Eigenschaft mit Präfix auf den Wert der benutzerdefinierten Eigenschaft festzulegen:

 * { --clip-path: initial; -webkit-clip-path: var(--clip-path); clip-path: var(--clip-path); }

Danach muss nur noch der Wert der benutzerdefinierten Eigenschaft in einem Selektor geändert werden:

 header { --clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - 2.5em), 0% 100%); }

Wenn Sie mehr darüber erfahren möchten, lesen Sie Leas vollständigen Artikel über die automatische Präfixierung mit CSS-Variablen.

Bulletproofing von benutzerdefinierten CSS-Eigenschaften

Wie bereits erwähnt, ist die Browserunterstützung für benutzerdefinierte CSS-Eigenschaften immer noch weitgehend nicht standardisiert. Wie kann dies also überwunden werden?

Hier kommt PostCSS und sein Plugin postcss-css-variables ins Spiel.

Falls Sie sich fragen, was PostCSS ist, lesen Sie meinen Artikel PostCSS: SASS's New Play Date, und kommen Sie darauf zurück, nachdem Sie fertig sind. Sie haben dann eine grundlegende Vorstellung davon, was Sie mit diesem erstaunlichen Tool tun können, und fühlen sich beim Lesen des restlichen Artikels nicht desorientiert.

Mit dem postcss-css-variables und seiner auf true gesetzten Preserve-Option können wir alle var() Funktionsdeklarationen in der Ausgabe preserve und den berechneten Wert als Fallback-Deklaration verwenden. Es behält auch die berechneten --var -Deklarationen bei. Denken Sie daran, dass mit diesem PostCSS-Plug-in benutzerdefinierte Eigenschaften nach dem Transpilationsprozess dynamisch aktualisiert werden können, aber die Fallback-Werte gleich bleiben, es sei denn, sie werden speziell ausgerichtet und explizit individuell geändert.

Wenn Sie nach einer Prä-/Postprozessor-freien Möglichkeit suchen, CSS-Variablen zu verwenden, können Sie die aktuelle Unterstützung jederzeit manuell mit der CSS- @support Regel überprüfen und einen geeigneten Fallback anwenden, wenn die Unterstützung lückenhaft oder nicht vorhanden ist. Zum Beispiel:

 :root { --color-blue: #1e90ff; /* hex value for dodgerblue color */ } .element { background: var(--color-blue); } @supports (not(--value: 0)) { /* CSS variables not supported */ .element { background: dodgerblue; } }

Ändern des Werts einer benutzerdefinierten Eigenschaft mit JavaScript

Ich habe in diesem ganzen Artikel erwähnt, dass Variablen mit JavaScript aktualisiert werden können, also lassen Sie uns darauf eingehen.

Angenommen, Sie haben ein helles Design und möchten es in ein dunkles Design umwandeln, vorausgesetzt, Sie haben CSS wie das folgende:

 :root { --text-color: black; --background-color: white; } body { color: var(--text-color); background: var(--background-color); }

Sie können die benutzerdefinierten Eigenschaften --text-color und --background-color color wie folgt aktualisieren:

 var bodyStyles = document.body.style; bodyStyles.setProperty('--text-color', 'white'); bodyStyles.setProperty('--background-color', 'black');

Interessante Anwendungsfälle

Im Laufe der Jahre der Entwicklung und Diskussion über die Spezifikationen von benutzerdefinierten CSS-Eigenschaften haben sich einige interessante Anwendungsfälle herauskristallisiert. Hier sind ein paar Beispiele:

Thematisierung: Die Verwendung einer Reihe von Themen für eine Website ist ziemlich einfach, wenn CSS-Variablen implementiert werden. Möchten Sie eine helle oder dunkle Variante Ihres aktuellen Stils? Ändern Sie einfach den Wert einiger benutzerdefinierter Eigenschaften mit JavaScript, und Sie sind fertig.

Abstandsanpassungen: Müssen Sie den Abstand einer Website feinabstimmen, sagen wir eine Rinne zwischen Spalten? Ändern Sie den Wert einer einzelnen CSS-Variablen und sehen Sie, wie sich diese Änderung auf der gesamten Website widerspiegelt.

Vollständig dynamische calc()-Funktionen: Jetzt können Sie vollständig dynamische calc() Funktionen haben, indem Sie benutzerdefinierte Eigenschaften innerhalb dieser Funktionen verwenden, wodurch die Notwendigkeit entfällt, komplizierte oder kurzlebige Berechnungen in JavaScript durchzuführen und diese Werte dann bei jeder Instanz manuell zu aktualisieren.

Hauchen Sie Ihren CSS-Dateien neues Leben ein

Benutzerdefinierte CSS-Eigenschaften sind eine leistungsstarke und innovative Möglichkeit, Ihren Stylesheets mehr Leben einzuhauchen, indem sie zum ersten Mal vollständig dynamische Werte in CSS einführen.

Die Spezifikation befindet sich derzeit im Status einer Kandidatenempfehlung, was bedeutet, dass die Standardisierung gleich um die Ecke steht, ein guter Grund, sich intensiv mit dieser Funktion zu befassen und das Beste daraus zu machen.

  1. Hinweis: Wie Lea Verou am 22. April betonte, werden benutzerdefinierte Eigenschaften jetzt standardmäßig von fast allen gängigen Browsern unterstützt, ohne dass ein Flag geändert werden muss. Die Verwendung für die Produktion ist sicher, es sei denn, die Unterstützung älterer Browserversionen ist erforderlich.