Blog
Thematische Websites mit mehreren Farbschemata auf die einfache Art

Heutzutage unterstützen viele Betriebssysteme helle und dunkle Themen und sogar Webbrowser haben dank der Medienabfrage prefers-color-scheme damit begonnen, diese zu unterstützen.
In diesem Blogbeitrag erkläre ich Ihnen, wie Sie Farbschemata (Themes) in einer Webanwendung anwenden und wechseln können. Ich finde es wichtig, dass der Mechanismus einfach ist und die Codebasis wartbar bleibt (DRY).
Manchmal möchten Sie, dass der Benutzer das Farbschema umschalten kann. (Optional können Sie das anfängliche Farbschema auf das Betriebssystemschema einstellen).
Es gibt eine Benutzerinteraktion, also müssen wir jetzt JavaScript verwenden. Aber lassen Sie mich zunächst mit den CSS-Teilen beginnen.
Anstatt wie in den obigen Beispielen von einem Medienabfrage-Block abhängig zu sein, der fest in Ihrem Stylesheet kodiert ist, müssen wir uns auf etwas verlassen, das ein Benutzer auf einer laufenden Website ändern kann.
Eine sehr gängige Methode, dies zu tun, ist das Umschalten eines Klassennamens auf der Seite . Wenn die Klasse
Inhaltsverzeichnis
- Wenden Sie das Styling basierend auf dem Farbschema Ihres Betriebssystems mit CSS an.

- Manuelles Umschalten des Farbschemas anstelle der Ableitung vom OS

- Wie kann man dies im Maßstab anwenden?
- Mehr als ein Thema

- Optimieren der Lösung
- Fazit
Wenden Sie das Styling basierend auf dem Farbschema Ihres Betriebssystems mit CSS an.
Schauen wir uns kurz an, welche CSS-Regeln Sie anwenden müssen, um eine Website im dunklen Modus zu rendern, wenn das Betriebssystem ebenfalls auf den dunklen Modus eingestellt ist. Verpacken Sie Ihr Styling einfach in einen@media (prefers-color-scheme: dark) Block, um das Styling anzuwenden, wenn das Farbschema auf 'dunkel' eingestellt ist. Versuchen Sie, Ihre OS-Einstellung auf 'Dunkel' zu ändern, um zu sehen, wie der Text weiß auf schwarz statt schwarz auf weiß dargestellt wird.
Die dunklen Regeln setzen die Standardregeln außer Kraft. Wir verpacken den Standardstil nicht in eine 'helle' Medienabfrage, weil wir einen Fallback brauchen, falls es keine Browserunterstützung für diese Medienabfrage gibt.
Ich verwende TailwindCSS häufig, und es gibt eine eingebaute dark:-Variante, so dass Sie dies sogar nur mit HTML- und CSS-Klassen erreichen können.
(Beachten Sie, dass der Spielplatz von Tailwind selbst auch einen Schalter für das Thema hat: Inception!)
Manuelles Umschalten des Farbschemas anstelle der Ableitung vom OS
Warum Tailwind?
Das Hauptproblem beim Schreiben von wartbarem CSS ist, dass CSS global skaliert ist und Sie die Stile mit Hilfe der so genannten Spezifität strukturieren. Wenn die Codebasis wächst, wird Ihr CSS unwartbar, es sei denn, Sie wenden selbst eine Reihe von Konventionen an, wie BEM oder SMACCS. Tailwind löst dieses Problem, indem es eine Menge kurz gefasster Utility-Klassen erzeugt, die alle die Spezifität 1 haben. Sie streuen diese Klassen dort in Ihren HTML-Code ein, wo Sie sie brauchen. Wenn Sie Tailwind mit einem CSS-Prozessor verwenden, enthält Ihr Bundle nur die Klassen, die Sie verwenden, und nicht auch die nicht verwendeten Stile. (Das ist der Grund, warum die Material- und Bootstrap-Bibliotheken normalerweise so groß sind). Für jedes reine HTML/CSS-Codebeispiel habe ich sowohl Vanilla-CSS- als auch TailwindCSS-Sandboxen beigefügt, so dass Sie selbst vergleichen können, wie Tailwind Ihren Arbeitsablauf produktiver machen könnte, indem Sie weniger Code schreiben, um mehr zu erreichen.dark ist, können wir das Styling auf der Grundlage eines spezifischeren .dark .block Selektors überschreiben.
Entfernen Sie die Klasse dark in den folgenden Beispielen, um zu sehen, was ich meine.
Mit TailwindCSS können Sie immer noch die Variante dark: verwenden, aber um mit einer Containerklasse statt einer Medienabfrage umzuschalten, müssen Sie darkMode: 'class' in der Konfiguration einstellen.
Das nächste Problem ist, wie man die Klasse umschalten kann?
Wir brauchen einen Mechanismus in Javascript, um die Klasse umzuschalten. Zum Beispiel mit einer Dropdown-Auswahl oder einer Umschalttaste. Um ehrlich zu sein, können Sie dies auf jede beliebige Art und Weise mit Ihrem bevorzugten JavaScript-Framework implementieren. Oder Sie verwenden einfach Vanilla JS, wie ich es im folgenden Beispiel getan habe. Es ist nicht sehr wichtig (und gehört auch nicht in den Rahmen dieses Blogbeitrags), wie Sie es machen, solange die Klasse dark auf einem Container hinzugefügt und entfernt wird, der ein thematisches Styling haben sollte.
Wie kann man dies im Maßstab anwenden?
Die gegebenen Beispiele waren ziemlich klein und einfach. Wenn eine Anwendung wächst und Sie alles doppelt gestalten müssen, wird Ihre Codebasis ziemlich unübersichtlich. Selbst wenn Sie TailwindCSS verwenden, müssen Sie alle farbbezogenen Klassen paarweise anwenden. Sie werden überalltext-white dark:text-black sehen. Ausnahmen wie text-white text-darkgray werden wahrscheinlich nicht vorkommen, so dass die Anwendung der gleichen Tupel immer wieder eine Menge Kesselflickschusterei bedeutet und die Lesbarkeit und Wartbarkeit Ihres Codes nicht verbessert.
Auch die Größe der Pakete wird zunehmen, was eine Verschwendung von Ressourcen ist, wenn die Benutzer den Farbschema-Wechsler nicht verwenden.
Während die Variante :dark, wie alle Tailwind-Klassen, ziemlich direkt und niedrigschwellig ist, erstellen die meisten Designer eine dunkle Farbpalette, mit der sie alle hellen Farben ersetzen. Wenn also ein Text im hellen Modus schwarz ist, wird er im dunklen Modus immer weiß sein. Was wir also in der Praxis tun wollen, ist, eine Reihe von Farben durch eine andere Reihe von Farben zu ersetzen.
Ich werde Ihnen in diesem Abschnitt erklären, wie Sie das machen können, aber lassen Sie mich zunächst ein zweites "Skalierungs"-Problem vorstellen.
Mehr als ein Thema
Die Unterstützung von hellen und dunklen Schemata durch Ihren Browser und Ihr Betriebssystem ist ziemlich leistungsfähig und einfach, aber was, wenn Sie mehr als nur hell und dunkel unterstützen möchten? Zum Beispiel Rot, Grün und Blau? Soweit ich weiß, gibt es in jedem Betriebssystem nur helle und dunkle Farbschemata und die Medienabfrage spiegelt dies wider. Die Standardvariante 'dunkler Modus', die Teil von TailwindCSS ist, unterstützt nur den dunklen Modus, nicht einmal einen hellen Modus, weil sie davon ausgehen, dass der helle Modus der Standard ist. Es hängt von der Medienabfrage ab, denn TailwindCSS ist nur syntaktischer Zucker. Es sieht so aus, als ob Ihre einzige Option ein benutzerdefinierter Mechanismus ist, wie das klassenbasierte Farbschema, das wir gerade im vorherigen Abschnitt gesehen haben. Eine Klasse kann einen beliebigen Namen haben, nicht nurdark, sondern auch red, green oder blue.
Wenn wir dies genauso wie bei den dunklen und hellen Klassen implementieren würden, wäre das Ergebnis wie folgt:
Die schema-spezifischen CSS-Regeln sind nicht sehr DRY, also werden wir dies mit Hilfe von benutzerdefinierten CSS-Eigenschaften, auch bekannt als CSS-Variablen, umgestalten.
Fairerweise muss man sagen, dass ich in diesem Beispiel nicht viele Bytes eingespart habe, aber wenn Sie genau hinsehen, werden Sie sehen, dass die Farbpaletten einmal definiert werden und wir sie überall wiederverwenden können. Das bedeutet auch, dass die Primärfarbe in jeder CSS-Eigenschaft wie Rahmen, Hintergrund, Schlagschatten, Umriss und Farbverlauf angewendet werden kann. Und wenn Sie das Thema wechseln, werden alle var(--primary) Farben von red auf green umgestellt.
Der Vollständigkeit halber ist dies die gleiche Implementierung, aber dann mit TailwindCSS. Wir verwenden keine Tailwind-spezifischen Funktionen wie die dunkle Variante mehr. Der einzige Unterschied besteht also darin, dass weniger Code geschrieben werden muss und er leichter zu lesen ist (wenn Sie an Tailwind-Klassen gewöhnt sind).
Optimieren der Lösung
Wie bereits erwähnt, wird Ihre CSS-Ausgabedatei oder Ihr App-Bundle größer, wenn Stile für mehr als ein Thema enthalten sind. Ein sehr häufiger Ansatz für dieses (allgemeine) Problem ist die Aufteilung von Paketen und/oder das faule Laden. Die Optimierung der CSS- und Asset-Performance ist ein sehr umfangreiches Thema für sich, daher werde ich Ihnen zwei pragmatische Lösungen vorstellen, die von Ihrer Situation abhängen. Erstellen Sie eine Website mit mehreren Themen? Oder erstellen Sie mehrere Websites, die jeweils ein anderes Thema haben? Im ersten Fall müssen Sie das Design auf einer bereitgestellten und laufenden Website wechseln. Das angewandte Design hängt von der Farbschemaeinstellung des Betriebssystems oder dem ausgewählten Design in der Anwendung ab. Im zweiten Fall können die Websites auf verschiedenen Servern gehostet sein. Sie sind nicht miteinander verbunden und Sie sollten die CSS-Dateien pro Thema vorbereiten, wenn Sie die Anwendung kompilieren.Umschalten der Stilvorlage während der Laufzeit
Wenn Sie die Themes während der Laufzeit austauschen müssen, müssen Sie zunächst die CSS-Vars in eine Datei pro Theme verschieben. Anstelle einer index.css haben Sie dann index.css, palette-red.css, palette-blue.css und palette-green.css. Die Paletten-Dateien enthalten die CSS-Variablen, die in einen:root -Selektor eingeschlossen sind, so dass diese Variablen auf jedem DOM-Element verwendet werden können. Die Datei index.css enthält den Rest der Stile.
Dann brauchen Sie auch kein Thema mit einem Klassennamen auszuwählen, sondern Sie tauschen stattdessen CSS-Dateien aus.
Umschalten der Stilvorlage für die Bauzeit
Wenn Sie 3 verschiedene Websites in 3 verschiedenen Themen erstellen, können Sie eine CSS-Datei 3 Mal erstellen. Sie brauchen keine CSS-Variablen mehr (das sind Laufzeitvariablen!). Fügen Sie die Farben einfach direkt in 3 separate tailwind.config.js-Dateien ein. Um eine Menge doppelten Konfigurationscode zu vermeiden, importieren Sie die Basiskonfiguration und fügen Sie sie in Ihre Tailwind-Konfigurationsdateien ein. Erstellen Sie das Projekt dann 3 Mal, jedes Mal mit einer anderen Tailwind-Konfiguration. Da diese Lösung ein wenig Technik erfordert, ist es nicht möglich, dies anhand eines statischen CodePen- oder Tailwind Play-Beispiels zu demonstrieren. Daher habe ich ein GitHub-Projekt erstellt, das Sie selbst klonen und ausführen können. Besuchen Sie das Multi-Themen-Repositorium auf GitHub. Führen Sienpm run build:red aus, um die Website mit dem roten Thema in /dist/red zu erstellen. Führen Sie npm run build:blue nach /dist/blau aus.
Sie erraten nie, was npm run build:green macht.
Das Beispiel verwendet Vite, aber jedes Build-Tool ist ausreichend. Webpack, Vue CLI, React React App. Solange es einen PostCSS-Build-Schritt gibt, wird es funktionieren, denn TailwindCSS ist ein PostCSS-Plugin.
Sie können die Stile sogar separat kompilieren, indem Sie nur PostCSS (CLI) verwenden. Wenn Sie den Namen der Tailwind-Konfigurationsdatei über eine Umgebungsvariable an die PostCSS-Konfiguration übergeben, wird es funktionieren.
Fazit
Wann immer Sie dunkle/helle Themes wünschen, die vom Betriebssystem abgeleitet sind, oder zwischen zwei oder mehr beliebigen Themes wechseln möchten, ist CSS Ihr Freund! Anhand kleiner Live-Beispiele habe ich Ihnen gezeigt, wie Sie selbst eine schema-/themenbasierte Website erstellen können. Verpacken Sie Styling-Überschreibungen in die leistungsstarkeprefers-color-scheme Media Query, um schemaspezifische Stile zu ermöglichen, oder schalten Sie auf oberster Ebene (body) zwischen Klassen um, um programmatisch zu einem beliebigen Thema zu wechseln. Die Erstellung eines Theme-Umschalters erfordert etwas JS, aber das ist ziemlich einfach mit Event-Handlern und einer Logik zum Umschalten zwischen Klassen oder Theme-Stylesheets.
Wenn Sie mehrere Websites mit jeweils einem eigenen Thema benötigen, habe ich Ihnen gezeigt, wie Sie die Leistungsfähigkeit von PostCSS und TailwindCSS nutzen können, um einen parametrisierten Aufbau zu erstellen.
Es gibt noch weitere Tools in der Toolbox, wie z.B. das TailwindCSS Multi-Theme-Plugin, um Varianten zu erstellen, die über dark: hinausgehen. Oder verwenden Sie das color-scheme CSS-Eigenschaft, um die Stylesheets des Browser-Benutzers in ein bestimmtes Schema zu zwingen, damit die nativen Teile der Webseite bereits korrekt gestylt sind. Es gibt auch Framework-spezifische, benutzerdefinierte Lösungen wie mit Vue-Themen kommentierte Stilblöcke oder React ThemeProvider von styled-components oder Emotion.
Das sind zu viele Details, um sie in diesem Blogbeitrag zu erläutern, aber ich möchte Sie ermutigen, diese Techniken ebenfalls auszuprobieren!Verfasst von

Frank van Wijk
Frank is a senior frontend consultant focusing on quality and maintainability.
Contact
Let’s discuss how we can support your journey.



