Themes und Plugins aktualisieren, um automatischen Dunkelmodus zu unterstützen

Zuvor wurden alle Farben in Discourse als SCSS-Variablen gespeichert. Um automatisches Umschalten des Farbschemas für den Dunkelmodus zu unterstützen, haben wir diese Farben im Kern in benutzerdefinierte CSS-Eigenschaften umgewandelt. Sie können die vollständige Liste jetzt einfach im Inspektor einsehen:

Themes und Plugins müssen alle $color SCSS-Variablen, die in Stylesheets verwendet werden, auf die entsprechenden --color CSS-Eigenschaften umstellen. In den meisten Fällen handelt es sich dabei um eine einfache Suchen-und-Ersetzen-Aufgabe:

-   background-color: $primary-very-low;
+   background-color: var(--primary-very-low);

Es gibt jedoch einige Fälle, in denen ein Theme oder ein Plugin eine komplexere Variation einer Farbe verwendet, beispielsweise beim Abdunkeln oder Aufhellen mit SCSS-Farbfunktionen. Diese Fälle erfordern eine komplexere Refaktorierung, und dafür haben wir die Möglichkeit hinzugefügt, Farbdefinitionen in Themes und Plugins zu erweitern.

In Plugins

Dieser Commit im discourse-encrypt-Plugin ist ein gutes und einfaches Beispiel für eine solche Refaktorierung. Er verschiebt eine mix($color1, $color2) SCSS-Deklaration in eine separate Datei und speichert sie als CSS-Benutzereigenschaft. Anschließend wird die neue Datei als :color_definitions-Asset registriert, was sicherstellt, dass die neu deklarierte Farbeigenschaft in das Stylesheet für Farbdefinitionen aufgenommen wird.

In Themes

In Themes können Sie dasselbe tun, indem Sie CSS-Benutzereigenschaften in der Stylesheet-Datei common/color_definitions.scss deklarieren. Ein Beispiel hierfür finden Sie in diesem Commit im graceful-Theme.

Einige zusätzliche Hinweise

  • Wenn transparente Farben über die Funktion rgba($color, 0.5) verwendet werden, akzeptiert SCSS HEX- und RGB-Farben als ersten Parameter, während CSS-Benutzereigenschaften nur eine RGB-Farbe akzeptieren. Deshalb haben wir den Hilfsfunktion hexToRGB() und einige Eigenschaften mit dem Suffix --rgb in den Farbdefinitionen eingeführt. Ein Beispiel:
// color_definitions.scss
:root {
  --primary: #{$primary};
  --primary-rgb: #{hexToRGB($primary)};
}

// anderes Stylesheet
.element {
  background-color: rgba(var(--primary-rgb), 0.05);
}
  • Beachten Sie, dass in dem obigen Snippet die SCSS-Variable interpoliert wird, wenn sie an eine benutzerdefinierte Eigenschaft übergeben wird. Dies ist eine Anforderung in SCSS, siehe Sass: Property Declarations für weitere Details.
  • Die CSS var()-Deklaration kann einen zweiten Wert als Fallback verwenden, falls der erste nicht verfügbar ist, z. B. wenn Sie var(--color1, red) schreiben, wird CSS auf die Farbe Rot zurückfallen, falls die Eigenschaft --color1 nicht gefunden wird. In Plugins verwenden wir die SCSS-Farbvariablen als Fallbacks, um die Kompatibilität mit früheren Versionen von Discourse zu gewährleisten. Das frühere Beispiel würde mit einem Fallback wie folgt aussehen:
-   background-color: $primary-very-low;
+   background-color: var(--primary-very-low, $primary-very-low);

Dieses Dokument wird versioniert – schlagen Sie Änderungen auf github vor.

24 „Gefällt mir“

Ich bin damit nicht sehr vertraut, und es wird eine Weile dauern, bis ich das selbst herausfinde. … Bedeutet das, dass alle Themen, die zuvor Farben referenziert haben, jetzt kaputt gehen?

6 „Gefällt mir“

Nein, überhaupt nicht. SCSS-Variablen in Themes werden noch lange funktionieren.

Allerdings bleiben Farben, die über SCSS-Variablen ausgegeben werden, statisch, d. h. sie können nicht dynamisch auf ein neues Farbschema umgestellt werden, wenn der Browser vom Normalmodus in den Dunkelmodus wechselt. Diese Themes/Plugins funktionieren also weiterhin, sind jedoch nicht mit dem automatischen Wechsel in den Dunkelmodus kompatibel.

13 „Gefällt mir“

Danke für die Anweisungen. Gibt es eine Möglichkeit, das Hintergrundbild je nach Dunkel-/Hellmodus zu ändern? (Ich habe dafür die Komponente für den Themeswitcher verwendet.) Wäre eine CSS-Klasse möglich, die den Modus anzeigt?

2 „Gefällt mir“

Tolle Frage! Ich habe das ausprobiert und festgestellt, dass wir die Verwendung von Hintergrundbildern oder Theme-Variablen in der speziellen Stylesheet-Datei für Farbddefinitionen bisher nicht korrekt unterstützt haben. Daher habe ich einige Korrekturen im Core vorgenommen. Du solltest das jetzt können (stell sicher, dass du den neuesten Core pullt).

Wenn du also zwei Bilder in deinem Theme oder Theme-Komponente hast, mit den SCSS-Variablen $bg-light und $bg-dark, kannst du dies zu deiner color_definitions.scss-Stylesheet-Datei hinzufügen:


$bg: url(dark-light-choose($bg-light, $bg-dark));

:root {
  --custom-bg: #{$bg};
}

Anschließend kannst du var(--custom-bg) in deinem regulären Stylesheet verwenden.

8 „Gefällt mir“

Für ein Bild müssen Sie nur die CSS-Media-Abfrage prefers-dark-theme in der Standardversion verwenden.

Das wird nicht in allen Fällen gut funktionieren, da die Media-Query die Präferenzen des Benutzers nicht kennt. Benutzer können das automatische Umschalten des Dunkelmodus deaktivieren, aber die Media-Query wird davon nichts mitbekommen, und es wird dazu führen, dass der Hintergrund für das dunkle Farbschema gerendert wird.

4 „Gefällt mir“

Ist es möglich, dass Discourse auch eine CSS-Klasse zum <body>-Tag für das Farbschema oder die Farbschema-ID hinzufügt? Es scheint, als wäre das viel einfacher.

Ich versuche, ein Problem bei der Konvertierung eines Themes zu lösen, bei dem ich viele verschiedene CSS-Regeln und Variablen benötige, und es entwickelt sich zu einem komplexen Durcheinander in der Datei color_definitions.scss.

Wenn ich in einer isolierten SCSS-Datei im Theme einfach so etwas tun könnte, würde es 5 Minuten dauern, etwas zu tun, für das ich mit color_definitions.scss lange brauche, um es herauszufinden:

body.dark-palette .some-thing {
  // some styles
}

body.light-palette .some-thing {
  // some styles
}

Ja, man kann viele Codezeilen in den Farldefinitionsdateien haben, insbesondere für Farbverläufe.

Es ist meiner Meinung nach immer noch der am besten geeignete „Ort“ dafür. Es ist zwar vom Element entfernt, das es verwendet, aber es ist ein praktischer, einzelner Ort, der Farben/Farbverläufe verarbeitet, die sich je nach Licht-/Dunkelmodus ändern.

Eine Alternative ist die Verwendung von etwas wie diesem:

@container style(--scheme-type: light){
  body{
    background: red;
  }
}

Unsere Farbschemata verfügen über eine Eigenschaft --scheme-type, die für helle Schemata light und für dunkle Schemata dark ist. Neuere Browser unterstützen Containerabfragen, sodass dies das tun sollte, was Sie hier versuchen zu erreichen, ohne der Body-Seite eine Klasse hinzuzufügen.

Meine CSS/SCSS-Kenntnisse sind nicht besonders gut. Vielleicht ist das für Leute, die sich damit auskennen, einfacher.

Es hat die Datei color_definitions.scss unübersichtlich gemacht, also habe ich sie in eine andere Datei in scss/ verschoben, damit ich sie importieren kann. Ich bin mir nicht sicher, wie ich das alles benennen soll, daher sieht es so aus.

Ich denke, es wäre einfacher, dies mit einer Body-Klasse (oder vielleicht einigen weiteren Beispielen) zu tun, aber auf jeden Fall funktioniert es vorerst. Ich weiß nicht, wie Container Queries funktionieren, aber das werde ich später recherchieren.

Beachten Sie, dass Style-Abfragen für benutzerdefinierte Eigenschaften unter Firefox nicht funktionieren (Stand: 14.11.2025).