Erstellen von Farbthemen mit benutzerdefinierten Eigenschaften, HSL und ein wenig calc()

Avatar of Dieter Raber
Dieter Raber am

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

Vor dem Aufkommen von CSS-benutzerdefinierten Eigenschaften (wir könnten sie in diesem Artikel „Variablen“ nennen, da das ihr Geist ist) bedeutete die Implementierung mehrerer Farbschemata auf derselben Website normalerweise das Schreiben separater Stylesheets. Definitiv nicht die wartungsfreundlichste Sache der Welt. Heutzutage können wir jedoch Variablen in einem einzigen Stylesheet definieren und CSS die Magie wirken lassen.

Selbst wenn Sie kein benutzergeneriertes oder vom Benutzer gewähltes Farbschema anbieten, können Sie das Konzept des Themas auf Ihrer Website dennoch nutzen. Es ist zum Beispiel ziemlich üblich, verschiedene Farbschemata in verschiedenen Bereichen der Website zu verwenden.

Wir werden ein Beispiel wie dieses erstellen

Gleiches Layout, andere Farben.

In diesem Beispiel ist alles, was sich zwischen den Abschnitten ändert, der Farbton ; die Variationen in der Helligkeit sind immer gleich. Hier ist ein Beispiel für eine vereinfachte Farbpalette für einen bestimmten Farbton

Eine Palette mehrerer Farbtöne könnte etwa so aussehen

Dies wäre mit RGB-Farbwerten mühsam, aber in HSL ändert sich nur ein Wert.

Benutzerdefinierte Eigenschaften eingeben

Benutzerdefinierte Eigenschaften gibt es schon seit einiger Zeit und sie werden weitgehend unterstützt. Polyfills und andere Lösungen für IE 11 sind ebenfalls verfügbar.

Die Syntax ist der traditionellen CSS-Syntax sehr ähnlich. Hier ist ein Überblick über die grundlegende Verwendung

Es ist üblich, Variablen auf dem Pseudo-Element :root zu definieren, das in HTML immer <html> ist, aber mit höherer Spezifität. Nichtsdestotrotz können Variablen auf jedem Element definiert werden, was nützlich ist, um bestimmte Variablen auf bestimmte Elemente zu beschränken. Zum Beispiel hier Variablen, die auf Datenattributen definiert sind

Calc() hinzufügen

Variablen müssen keine festen Werte sein. Wir können die Leistung der calc()-Funktion nutzen, um Werte automatisch für uns zu berechnen und dabei ein einheitliches Muster einzuhalten

Da CSS keine Schleifen unterstützt, wäre ein Präprozessor praktisch, um einen Teil des Codes zu generieren. Aber denken Sie daran: CSS-Variablen sind nicht dasselbe wie Sass-Variablen.

CSS-Variablen implementieren

Was wir im Grunde tun wollen, ist, die Farbe derselben Komponente in verschiedenen Abschnitten derselben Seite zu ändern. So

Wir haben drei Abschnitte in Tabs mit eigenen IDs: #food, #lifestyle und #travel. Jeder Abschnitt entspricht einem anderen Farbton. Das  data-theme-attribute am div.wrapper-Element definiert, welcher Farbton gerade verwendet wird.

Wenn #travel der aktive Tab ist, verwenden wir die Variable --first-hue, die den Wert 180° hat. Das ist es, was als --hue-Wert für den Abschnitt verwendet wird, was zu einer teal-Farbe führt

<div class="wrapper" data-theme="travel">
.wrapper[data-theme="travel"] {
  --hue: var(--first-hue);  /* = 180° = teal */
}

Das Klicken auf einen der Tabs aktualisiert das data-theme-Attribut auf die ID des Abschnitts und entfernt den Hash (#) daraus. Das erfordert ein bisschen JavaScript. Das ist eine der (vielen) schönen Dinge an CSS: Sie können mit JavaScript darauf zugegriffen und sie manipuliert werden. Das ist weit entfernt von Präprozessor-Variablen, die zum Zeitpunkt des Build-Prozesses in Werte kompiliert werden und im DOM nicht mehr zugänglich sind.

<li><a href="#food">Food</a></li>
const wrapper = document.querySelector('.wrapper');
document.querySelector("nav").addEventListener('click', e => {
  // Get theme name from URL and ditch the hash
  wrapper.dataset.theme = e.target.getAttribute('href').substr(1);
})

Progressive Enhancement

Wenn wir JavaScript verwenden, sollten wir Szenarien bedenken, in denen ein Benutzer es deaktiviert hat. Andernfalls sind unsere Skripte – und damit auch unsere Benutzeroberfläche – unzugänglich. Dieser Ausschnitt stellt sicher, dass die Website-Inhalte auch in diesen Situationen noch zugänglich sind

// progressive enhancement:
// without JavaScript all sections are displayed, the theme is only set when the page loads
wrapper.dataset.theme = wrapper.querySelector('section').id;

Dies ermöglicht lediglich, dass die Tabs zum entsprechenden Abschnitt nach oben auf der Seite scrollen. Sicher, das Theming ist weg, aber die Bereitstellung von Inhalten ist viel wichtiger.

Während ich mich für einen Single-Page-Ansatz entschieden habe, ist es auch möglich, die Abschnitte als separate Seiten zu servieren und [data-theme] serverseitig festzulegen. 

Ein weiterer Ansatz

Bisher sind wir davon ausgegangen, dass sich Farbwerte linear ändern und somit einem mathematischen Ansatz unterliegen. Aber auch in Situationen, in denen dies nur teilweise zutrifft, können wir möglicherweise vom selben Konzept profitieren. Wenn zum Beispiel die Helligkeit einem Muster folgt, der Farbton aber nicht, könnten wir das Stylesheet wie folgt aufteilen

<head>
  <style>
    :root {
      --hue: 260;
    }
  </style>
  <link rel="stylesheet" href="stylesheet-with-calculations-based-on-any-hue.css">
</head>

Web-Komponenten unterstützen

Web-Komponenten sind ein spannendes (und sich entwickelndes) Konzept. Es ist verlockend zu glauben, dass wir gekapselte Komponenten haben können, die überall wiederverwendet und von Fall zu Fall thematisiert werden können. Eine Komponente mit vielen Kontexten!

Wir können CSS-Variablen-Theming mit Web-Komponenten verwenden. Es erfordert die Verwendung eines host-context()-Pseudo-Selektors. (Dank an habemuscode dafür, dass er mich darauf aufmerksam gemacht hat!)

:host-context(body[data-theme="color-1"]) {
  --shade-1: var(--outsideHSL);
}

Zusammenfassend…

Das Theming einer Website mit CSS-benutzerdefinierten Eigenschaften ist viel einfacher als die Workaround-Ansätze, auf die wir uns in der Vergangenheit verlassen haben. Es ist wartungsfreundlicher (ein Stylesheet), performanter (weniger Code) und eröffnet neue Möglichkeiten (Verwendung von JavaScript). Ganz zu schweigen davon, dass CSS-benutzerdefinierte Eigenschaften noch leistungsfähiger werden, wenn sie mit HSL-Farben und der calc()-Funktion verwendet werden.

Wir haben gerade ein Beispiel betrachtet, bei dem wir das Farbthema einer Komponente basierend auf dem Abschnitt ändern können, in dem sie verwendet wird. Aber wieder gibt es hier viel mehr Möglichkeiten, wenn wir dazu übergehen, Benutzern zu ermöglichen, Themen selbst zu ändern – ein Thema, das Chris in diesem Artikel behandelt.