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

Non sono molto bravo in queste cose e mi ci vorrà un po’ per capire come fare da solo… Significa che tutti i temi che facevano riferimento ai colori in precedenza ora si romperanno?

6 Mi Piace

No, affatto. Le variabili SCSS nei temi continueranno a funzionare per molto tempo.

Tuttavia, i colori generati tramite variabili SCSS rimarranno statici, ovvero non potranno essere cambiati dinamicamente in una nuova combinazione di colori quando il browser passa dalla modalità normale a quella scura. Quindi quei temi e plugin continueranno a funzionare, ma non saranno compatibili con il cambio automatico alla modalità scura.

13 Mi Piace

Grazie per le istruzioni. C’è un modo per cambiare anche l’immagine di sfondo in base alla modalità scura/chiara? (Ho utilizzato il componente del selettore di tema per farlo.) Sarebbe possibile utilizzare una classe CSS che indichi la modalità?

2 Mi Piace

Ottima domanda. Ho provato questa soluzione e ho notato che non supportavamo correttamente l’uso di immagini di sfondo o variabili del tema nelle definizioni speciali del foglio di stile dei colori. Quindi ho apportato alcune correzioni nel core: ora dovresti essere in grado di farlo (assicurati di aggiornare l’ultima versione del core).

Quindi, se hai due immagini nel tuo tema o nel componente del tema, con le variabili SCSS $bg-light e $bg-dark rispettivamente, puoi aggiungere questo al tuo foglio di stile color_definitions.scss:


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

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

E poi puoi utilizzare var(--custom-bg) nel tuo foglio di stile regolare.

8 Mi Piace

Per un’immagine, tutto ciò che serve è la media query CSS vanilla prefers-dark-theme.

Ciò non funzionerà bene in tutti i casi, perché la query media non tiene conto delle preferenze dell’utente. Gli utenti possono disattivare il passaggio automatico alla modalità scura, ma la query media non ne sarà a conoscenza e ciò comporterà il rendering dello sfondo destinato allo schema di colori scuro.

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).