Aggiorna temi e plugin per supportare la modalità scura automatica

In precedenza, tutti i colori in Discourse erano memorizzati come variabili SCSS. Per supportare il cambio automatico dello schema di colori in modalità scura, abbiamo convertito questi colori nel core in proprietà CSS personalizzate. È possibile visualizzare facilmente l’elenco completo nell’ispettore ora:

Temi e plugin devono sostituire tutte le variabili SCSS $color utilizzate nei fogli di stile con gli equivalenti in proprietà CSS --color. Nella maggior parte dei casi, si tratta di una semplice operazione di trova e sostituisci:

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

Ma ci sono alcuni casi in cui un tema o un plugin utilizza una variazione più complessa di un colore, ad esempio quando scurisce o schiarisce utilizzando le funzioni colore SCSS. Questi casi richiedono un refactoring più complesso, e per questo abbiamo aggiunto la capacità di estendere le definizioni di colore nei temi e nei plugin.

Nei plugin

Questo commit nel plugin discourse-encrypt è un buon e semplice esempio di tale refactoring. Sposta una dichiarazione SCSS mix($color1, $color2) in un file separato e la memorizza come proprietà personalizzata CSS. Quindi il nuovo file viene registrato come asset :color_definitions, il che assicura che la proprietà colore appena dichiarata sia inclusa nel foglio di stile delle definizioni di colore.

Nei temi

Nei temi, è possibile fare la stessa cosa dichiarando proprietà CSS personalizzate nel foglio di stile common/color_definitions.scss. È possibile consultare questo commit nel tema graceful per un esempio.

Alcune note aggiuntive

  • quando si utilizzano colori trasparenti tramite la funzione rgba($color, 0.5), SCSS accetta colori HEX e RGB nel primo parametro, mentre le proprietà CSS personalizzate accettano solo un colore RGB. Ecco perché abbiamo introdotto l’helper hexToRGB() e alcune proprietà con il suffisso --rgb nelle definizioni di colore. Un esempio:
// color_definitions.scss
:root {
  --primary: #{$primary};
  --primary-rgb: #{hexToRGB($primary)};
}

// other stylesheet
.element {
  background-color: rgba(var(--primary-rgb), 0.05);
}
  • si noti che nello snippet sopra, la variabile SCSS è interpolata quando viene passata a una proprietà personalizzata. Questo è un requisito in SCSS, vedere Sass: Property Declarations per maggiori dettagli.
  • la dichiarazione CSS var() può avere un fallback a un secondo valore se il primo non è disponibile, ad esempio, scrivendo var(--color1, red), CSS utilizzerà il colore rosso come fallback se la proprietà --color1 non viene trovata. Nei plugin, utilizziamo le variabili colore SCSS come fallback per garantire la compatibilità con le versioni precedenti di Discourse. Quindi l’esempio precedente, apparirebbe così con un fallback:
-   background-color: $primary-very-low;
+   background-color: var(--primary-very-low, $primary-very-low);

Questo documento è controllato tramite versione - suggerisci modifiche su github.

24 Mi Piace

I’m not very good at this stuff and it’ll take me a while to figure this out myself. . . Does this mean that all themes that referred to colors before are now going to be broken?

6 Mi Piace

No, not at all. SCSS variables in themes will continue to work for a long time.

But any colors outputted via SCSS variables will stay static, i.e. they cannot be dynamically switched to a new color scheme when a browser goes from normal to dark mode. So those themes/plugins will continue to work, they just won’t be compatible with automatic dark mode switching.

13 Mi Piace

Thanks for the instructions. Is there a way to also change a background image depending on dark/light mode? (I’ve used the theme switcher component to do that.) Would a CSS class indicating the mode be possible?

2 Mi Piace

Great question, I tried this and noticed that we didn’t properly support using background images or theme variables in the special color definitions stylesheet. So I made some fixes in core, and you should be able to do this now (make sure you pull the latest core).

So, if you have two images in your theme or theme component, with SCSS vars of $bg-light and $bg-dark respectively, you can add this to your color_definitions.scss stylesheet:


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

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

And then you can use var(--custom-bg) in your regular stylesheet.

8 Mi Piace

For an image, all you need to do is the vanilla prefers-dark-theme CSS media query.

That won’t work well in all cases, because the media query is not aware of the user’s preferences. Users can disable auto-dark-mode switching, but the media query won’t be aware of that, and it will result in the background meant for the dark color scheme being rendered.

4 Mi Piace

È possibile per Discourse aggiungere anche una classe CSS all’elemento <body> per lo schema di colori o l’ID dello schema di colori? Sembra che sarebbe molto più facile.

Sto cercando di risolvere un problema durante la conversione di un tema in cui ho bisogno di molte regole CSS e variabili diverse, e sta diventando un pasticcio complesso nel file color_definitions.scss.

Se potessi semplicemente fare qualcosa del genere in un file SCSS isolato nel tema, ci vorrebbero 5 minuti per fare qualcosa che richiede molto tempo per essere capito con color_definitions.scss:

body.dark-palette .some-thing {
  // alcuni stili
}

body.light-palette .some-thing {
  // alcuni stili
}

Sì, si può finire con molte righe di codice nei file di definizione dei colori, in particolare per le sfumature.

Nella mia mente è ancora il “posto” più appropriato. È lontano dall’elemento in cui viene utilizzato, sì, ma è un unico posto conveniente che gestisce colori/sfumature che cambiano in base alla modalità chiara/scura.

Un’alternativa è usare qualcosa di simile:

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

I nostri schemi di colori sono dotati di una proprietà --scheme-type che è light per gli schemi chiari e dark per gli schemi scuri. I browser recenti supportano le container queries, quindi questo dovrebbe fare ciò che stai cercando di realizzare senza aggiungere una classe al body della pagina.

Le mie competenze CSS/SCSS non sono eccezionali. Forse è più facile per chi è esperto in queste cose.

Stava creando confusione nel file color_definitions.scss, quindi l’ho spostato in un altro file in scss/ per poterlo importare. Non sono sicuro di come chiamare tutto, quindi ora assomiglia a questo.

Penso che sarebbe più facile farlo con una classe body (o forse con alcuni altri esempi), ma in ogni caso, per ora funziona. Non so come funzionano le container queries, ma lo ricercherò più tardi.

Si noti che le query di stile per le proprietà personalizzate non funzionano su Firefox a partire da oggi (14/11/2025).