Wir haben vor Kurzem über den Unterschied zwischen nativen CSS-Variablen (Custom Properties) und Präprozessor-Variablen gepostet. Es gibt einige esoterische Dinge, die Präprozessor-Variablen tun können, die native Variablen nicht können, aber meistens können native Variablen die gleichen Dinge tun. Sie sind jedoch leistungsfähiger, da sie live interpoliert werden. Wenn sich ihre Werte jemals ändern (z. B. JavaScript, Medienabfrage-Treffer usw.), löst die Änderung eine sofortige Änderung auf der Website aus.
Cool, oder? Aber immer noch, wie nützlich ist das eigentlich? Was sind die Hauptanwendungsfälle? Ich denke, wir sehen immer noch, wie sich diese entwickeln.
Ein Anwendungsfall, wie mir einfiel, wäre das Theming einer Website (denken Sie: benutzerdefinierte Farben für Elemente auf einer Website). Anstatt unterschiedliche CSS für eine Reihe verschiedener Themes zu schreiben oder JavaScript zu schreiben, das auf alle Elemente abzielt, die wir ändern wollen, und diese zu ändern), schreiben wir einfach ein Basisset von CSS, das Variablen verwendet, und setzen diese Variablen auf die Theme-Farben.
Stellen Sie sich vor, wir erlauben die Anpassung des Hintergrunds von Header und Footer unserer Website.
header {
background: var(--mainColor);
}
...
footer {
background: var(--mainColor);
}
Vielleicht gibt es eine Unterüberschrift mit einer dunkleren Variante dieser Farbe. Hier ist ein kleiner Trick, um eine transparente Farbschicht über eine andere zu legen
.subheader {
background:
/* Make a bit darker */
linear-gradient(
to top,
rgba(0, 0, 0, 0.25),
rgba(0, 0, 0, 0.25)
)
var(--mainColor);
}
Woher kommt --mainColor?
Beim Theming ist die Idee, dass Sie den Benutzer danach fragen. Glücklicherweise haben wir Farbauswahlfelder
<input type="color">
Und Sie könnten diesen Wert in einer Datenbank oder einem anderen Speicherungsmechanismus speichern, den Sie wünschen. Hier ist eine kleine Demo, bei der der Wert in localStorage gespeichert wird
Der Wert wird aus localStorage ausgelesen und beim Laden der Seite verwendet. Ein Standardwert wird ebenfalls (in CSS) festgelegt, falls dieser nicht existiert.
Was diese Demo für mich so überzeugend macht, ist, wie wenig Code es ist. Die Wartung als Funktion auf einer Website ist weitgehend eine CSS-Angelegenheit und scheint flexibel genug, um dem Test der Zeit (wahrscheinlich) standzuhalten.
Nicht ungewöhnlich, ich war bei diesem Thema weit im Rückstand.
Viele Leute denken beim Theming an einen der Hauptanwendungsfälle für CSS Custom Properties. Schauen wir uns einige Beispiele anderer Leute an.
Giacomo Zinetti hat die gleiche Art von Farbauswahl-Implementierung
Beispiele und Ratschläge von Harry Roberts
Er schrieb „Pragmatic, Practical, and Progressive Theming with Custom Properties“, in dem er auf Apps wie Twitter und Trello hinwies, die Theming direkt für Benutzer anbieten.

Harry macht viel Beratung und zu meiner Überraschung arbeitet er mit Unternehmen zusammen, die dies sehr viel tun wollen. Er warnt
Theming ist die überwiegende Mehrheit der Zeit ein reiner „Nice-to-have“. Es ist nicht geschäftskritisch oder normalerweise nicht einmal wichtig. Wenn Sie aufgefordert werden, ein solches Theming bereitzustellen, tun Sie dies nicht auf Kosten der Leistung oder der Codequalität.
In Sass / In React
In einer realen Anwendung des Themings durch Custom Properties erzählt Dan Bahrami davon, wie sie es bei Geckoboard gemacht haben, dem Produkt, an dem er arbeitet.

Es ist ein React-Produkt, aber sie verwenden keine JavaScript-Styles, daher haben sie sich entschieden, das Theming mit Custom Properties über Sass durchzuführen.
@mixin variable($property, $variable, $fallback) {
#{$property}: $fallback;
#{$property}: var($variable);
}
Sie können also tun
.dashboard {
@include variable(background, --theme-primary-color, blue);
}
Was zu einer Fallback-Lösung kompiliert
.dashboard {
background: blue;
background: var(--theme-primary-color);
}
Sie haben auch react-custom-properties entwickelt, das sich ausschließlich auf die Anwendung von Custom Properties auf Komponenten konzentriert und die Tatsache nutzt, dass Sie Custom Properties als Inline-Styles festlegen können.
<div style="--theme-primary-color: blue;">
</div>
Mehr als eine Farbe und Eigenschaft
Es sind nicht nur Farben, die sich ändern können, eine Custom Property kann jeder gültige Wert sein. Hier ist Keith Clark mit einer Demo mit mehreren Farben sowie Schriftgrößen
Und David Darnes mit integriertem Theming in einer Jekyll-Website
Microsoft Demo
Greg Whitworth erstellte diese Demo (jetzt offline, tut mir leid)

Welche Farb-Modifikatoren innerhalb der Farb-Funktionen selbst verwendet
.distant-building__window {
fill: rgb(
calc(111 + (111 * var(--building-r-mod))),
calc(79 + (79 * var(--building-g-mod))),
calc(85 + (85 * var(--building-b-mod)))
);
}
Was nicht in allen Browsern unterstützt wird.
Greg wies auch darauf hin, dass CSS4-Farb-Funktionen (die wir bereits behandelt haben) all diese Theming-Sachen noch leistungsfähiger machen werden.
Das Polymer-Projekt thematisiert über Custom Properties
Zumindest tat es das in der v1-Dokumentation. Die Idee ist, dass Sie eine Web-Komponente hätten, wie
<iron-icon icon="[[toggleIcon]]">
</iron-icon>
Die intelligente Standardwerte hatte, aber speziell für das Styling durch Theming entwickelt wurde.
<style>
iron-icon {
fill: var(--icon-toggle-color, rgba(0,0,0,0));
stroke: var(--icon-toggle-outline-color, currentcolor);
}
:host([pressed]) iron-icon {
fill: var(--icon-toggle-pressed-color, currentcolor);
}
</style>
Was bedeutete, dass Sie diese Variablen setzen und die Komponente neue Farben annehmen lassen konnten.
Unterstützung und Fallbacks
Die Unterstützung ist in letzter Zeit ziemlich gut geworden.
Diese Daten zur Browserunterstützung stammen von Caniuse, wo es mehr Details gibt. Eine Zahl gibt an, dass der Browser die Funktion ab dieser Version unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 49 | 31 | Nein | 16 | 10 |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 127 | 127 | 127 | 10.0-10.2 |
Opera Mini und IE fehlen bemerkenswert. Wir haben bereits die Idee eines Fallbacks behandelt, indem wir eine gültige Nicht-Variablen-Eigenschaft vor der mit einer Custom Property verwendeten festlegen.
Wie viele moderne CSS-Funktionen können Sie @supports verwenden, um auf Unterstützung zu testen, bevor Sie sie verwenden.
@supports (--color: red) {
:root {
--color: red;
}
body {
color: var(--color);
}
}
Es hängt immer von der Situation ab, aber die Platzierung von Fallbacks bei einer vorherigen Deklaration ist wahrscheinlich die nützlichste Art, mit Nicht-Unterstützung in CSS umzugehen. Es gibt auch Randfälle.
Michael Scharnagl dokumentiert eine JavaScript-Methode zum Testen.
if (window.CSS && window.CSS.supports && window.CSS.supports('--a', 0)) {
// CSS custom properties supported.
} else {
// CSS custom properties not supported
}
Farben und Barrierefreiheit
Beim Festlegen von Farben für Text und der Farbe dahinter ist der Kontrast zwischen diesen Farben ein Barrierefreiheitsproblem. Zu wenig Kontrast, zu schwer zu lesen.
Eine ziemlich gängige Lösung dafür ist, je nach Hintergrundfarbe zu wählen, ob der Text hell oder dunkel (weiß oder schwarz) sein soll.
David Halford hat eine Demo, die dies mit JavaScript berechnet.
Und Brendan Saunders mit Sass.
Hat jemand die Leistungsauswirkungen der Verwendung von mehr als einer Handvoll Custom Properties untersucht? Ich möchte sie in einem bevorstehenden Projekt verwenden, aber es könnte schwierig sein, wenn sie bei großen Mengen ruckelig werden.
Die Verwendung von Custom Properties zur Festlegung einer einzelnen Eigenschaft ist IMMER schneller als die Manipulation von Stilen an jedem einzelnen DOM-Knoten, der die benutzerdefinierten Stile benötigt.
Fast 100x schneller: https://jsperf.com/css-variables-vs-inline-styles
Ich verstehe diesen Abschnitt nicht wirklich.
Alles, was
@supportstut, ist eine Parser-Level-Überprüfung auf Unterstützung. Die verlinkte Version funktioniert einwandfrei. Zusätzlich nutzt dieCSS.supports()-Methode tatsächlich denselben zugrundeliegenden Code wie@supports; somit ist es dasselbe wie die deklarative Verwendung in Ihrem CSS. Dies kann immer noch verwendet werden, um festzustellen, ob ein Browser benutzerdefinierte Eigenschaften unterstützt oder nicht, da er fehlschlagen würde, wenn er sie nicht parsen kann.Ich habe diesen Teil korrigiert! Ich hatte das gelesen und dachte mir: oh nein, das ist seltsam. Aber ich schätze, das dreht sich alles darum, eine Variable einer anderen Variable zuzuweisen?
@chriscoyier
Ja, es kann etwas verwirrend sein, aber die Existenz oder Nichtexistenz der Variable ist irrelevant. Denken Sie daran, dass Sie nur testen, ob der Parser mit Custom Props funktioniert, nicht die Leistungsfähigkeit der Kaskade und all die anderen Faktoren von Custom Properties. Ich behandle das im Abschnitt Erkennung von Unterstützung für Custom Properties des Posts. Sie könnten buchstäblich Folgendes tun, was selbsterklärend ist:
Hier ist ein jsbin des obigen Codes und ein Screenshot mit Edge/IE11
Ich hoffe, das hilft bei der Klärung.
@chriscoyier
Außerdem danke für den Hinweis auf die Demo. Da ich bemerkt habe, dass Sie einen Browser verwenden, der Probleme mit calc() hat, habe ich ein GIF davon in Aktion auf Twitter gepostet. Ich möchte auch erwähnen, dass ich zwar die Programmierarbeit geleistet habe, aber die gesamte wunderbare Designarbeit von Stephanie Drescher stammt :)
Der „kleine Trick“, um mein
--mainColorabzudunkeln, ist brillant und ich werde ihn schamlos stehlen. Ich habe mit CSS-Variablen in einem kleinen Nebenprojekt herumgespielt und gerade eine Palette ausgewählt, und das vereinfacht alles.Schade, dass man die gleiche Technik nicht auf die automatische Anpassung von Textfarben anwenden kann.
Ich liebe den Trick mit der dunkleren Farbe auch! Danke Chris!
Gestern habe ich einen Snippet-Generator erstellt, der die Leistung von Custom Properties nutzt. Schaut mal rein, Leute.
https://pawelgrzybek.com/snippet-generator/
Vor ein paar Monaten habe ich es genutzt, um auch einen neuen Farbwechsler zu erstellen.
Demo
http://codepen.io/pawelgrzybek/pen/KVLmXQ
Artikel
https://pawelgrzybek.com/css-custom-properties-explained/
Hallo Chris,
Ich fühle mich geehrt, in einem CSS-Tricks-Artikel erwähnt zu werden! Danke für den Shoutout. Sie könnten daran interessiert sein, dass React 16 das Setzen von Custom Properties direkt in der
style-Prop eines Elements unterstützt. Zum Beispiel...<div style={{ ‘--my-color’ : ‘red’}} />
Toller Artikel, ich habe kürzlich mit diesem Zeug herumgespielt, einige coole Anwendungsfälle.
Erwähnenswert ist auch der eingebaute Fallback, falls die Variable nicht gesetzt ist.
color: var(--text-color, black);Wenn
--text-colornicht im Code vorhanden ist, wird standardmäßigblackverwendet.https://developer.mozilla.org/en-US/docs/Web/CSS/var#Browser_compatibility
Das habe ich vor etwa 8 Monaten in meinem Portfolio gemacht.
http://jsil.work/
Ich habe ein Schieberegler-Element mit jQuery an den Farbtonwert in HSL gekoppelt. Und dann die Variable in einem SVG und CSS-Elementen verwendet.
Vielen Dank für die Artikel, fast der gesamte Code, den ich verwendet habe, stammt aus CSS Tricks.
Ich möchte das in meine WordPress-Vorlagen einbauen. Meine Überlegung ist, wie in diesem Artikel in den lokalen Speicher zu schreiben und gleichzeitig mit der Customizer-API in der Datenbank zu speichern.
Auf diese Weise können die Benutzer ihre Änderungen sofort sehen. Sehen Sie Probleme mit diesem Ansatz? Das würde meine WP-Websites für meine Kunden „wixy“er machen und trotzdem alle WP-Vorteile beibehalten.
Also habe ich das geschafft.
Ich habe den lokalen Speicher nicht verwendet, da die Customizer-API eine eigene Vorschau-Callback hat. Ich muss zugeben, es ist ziemlich magisch, Farben und Schriftarten vom Customizer ändern zu sehen. Es ist super reibungslos und ich habe Sass-Fallbacks für IE usw.
Hier war mein Workflow
1. Neue Felder im WordPress-Customizer einrichten
2. js-Vorschau postMessage-Callbacks einrichten – siehe diesen Artikel
https://code.tutsplus.com/tutorials/customizer-javascript-apis-getting-started–cms-26838
3. Die gespeicherten Felder in admin-ajax-Variablen schreiben.
4. Diese Variablen beim Laden der Seite setzen.
Hinweis – Sie müssen einen Preloader implementieren, wenn Sie nicht möchten, dass Leute Farbänderungen sehen (ich habe lieber die CSS-Variablen asynchron gesetzt).
Toller Artikel und Demo von Stephanie Liu
http://ramenhog.com/blog/2017/06/07/theming-with-css-custom-properties