CSS Custom Properties und Theming

Avatar of Chris Coyier
Chris Coyier on

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

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

Auf seiner Website:

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

ChromeFirefoxIEEdgeSafari
4931Nein1610

Mobil / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712710.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.