Mettre à jour les thèmes et les plugins pour supporter le mode sombre automatique

Auparavant, toutes les couleurs dans Discourse étaient stockées sous forme de variables SCSS. Pour prendre en charge la bascule automatique du thème de couleur en mode sombre, nous avons converti ces couleurs dans le cœur en propriétés CSS personnalisées. Vous pouvez facilement voir la liste complète dans l’inspecteur maintenant :

Les thèmes et les plugins doivent remplacer toutes les variables SCSS $color utilisées dans les feuilles de style par les équivalents de propriétés CSS --color. Dans la plupart des cas, il s’agit d’une simple tâche de recherche et remplacement :

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

Mais il existe des cas où un thème ou un plugin utilise une variation plus complexe d’une couleur, par exemple, lors de l’assombrissement ou de l’éclaircissement à l’aide de fonctions de couleur SCSS. Ces cas nécessitent un refactoring plus complexe, et pour cela, nous avons ajouté la capacité d’étendre les définitions de couleurs dans les thèmes et les plugins.

Dans les plugins

Ce commit dans le plugin discourse-encrypt est un bon et simple exemple d’un tel refactoring. Il déplace une déclaration SCSS mix($color1, $color2) dans un fichier séparé et la stocke en tant que propriété personnalisée CSS. Ensuite, le nouveau fichier est enregistré en tant qu’actif :color_definitions, ce qui garantit que la propriété de couleur nouvellement déclarée est incluse dans la feuille de style des définitions de couleur.

Dans les thèmes

Dans les thèmes, vous pouvez faire la même chose en déclarant des propriétés CSS personnalisées dans la feuille de style common/color_definitions.scss. Vous pouvez consulter ce commit dans le thème graceful pour un exemple.

Quelques notes supplémentaires

  • lorsque vous utilisez des couleurs transparentes via la fonction rgba($color, 0.5), SCSS accepte les couleurs HEX et RVB dans le premier paramètre, tandis que les propriétés CSS personnalisées n’acceptent qu’une couleur RVB. C’est pourquoi nous avons introduit l’utilitaire hexToRGB() et certaines propriétés avec le suffixe --rgb dans les définitions de couleurs. Un exemple :
// color_definitions.scss
:root {
  --primary: #{$primary};
  --primary-rgb: #{hexToRGB($primary)};
}

// other stylesheet
.element {
  background-color: rgba(var(--primary-rgb), 0.05);
}
  • notez que dans l’extrait ci-dessus, la variable SCSS est interpolée lorsqu’elle est transmise à une propriété personnalisée. C’est une exigence en SCSS, voir Sass: Property Declarations pour plus de détails.
  • la déclaration CSS var() peut avoir une valeur de secours si la première n’est pas disponible, comme dans, lorsque vous écrivez var(--color1, red), CSS utilisera la couleur rouge si la propriété --color1 n’est pas trouvée. Dans les plugins, nous utilisons les variables de couleur SCSS comme valeurs de secours pour assurer la compatibilité avec les versions précédentes de Discourse. Ainsi, l’exemple précédent ressemblerait à ceci avec une valeur de secours :
-   background-color: $primary-very-low;
+   background-color: var(--primary-very-low, $primary-very-low);

Ce document est contrôlé par version - suggérez des modifications sur github.

24 « J'aime »

Je ne suis pas très doué dans ce domaine et il me faudra un certain temps pour comprendre cela moi-même… Cela signifie-t-il que tous les thèmes qui faisaient référence aux couleurs auparavant vont maintenant être cassés ?

6 « J'aime »

Non, pas du tout. Les variables SCSS dans les thèmes continueront de fonctionner pendant longtemps.

Cependant, les couleurs générées via les variables SCSS resteront statiques, c’est-à-dire qu’elles ne pourront pas être basculées dynamiquement vers un nouveau schéma de couleurs lorsque le navigateur passe du mode normal au mode sombre. Ainsi, ces thèmes et plugins continueront de fonctionner, mais ils ne seront tout simplement pas compatibles avec le basculement automatique vers le mode sombre.

13 « J'aime »

Merci pour les instructions. Existe-t-il un moyen de changer également l’image d’arrière-plan en fonction du mode sombre/clair ? (J’ai utilisé le composant de commutation de thème pour cela.) Serait-il possible d’utiliser une classe CSS indiquant le mode ?

2 « J'aime »

Bonne question. J’ai essayé cela et j’ai remarqué que nous ne prenions pas correctement en charge l’utilisation d’images de fond ou de variables de thème dans la feuille de style des définitions de couleurs spéciales. J’ai donc apporté quelques correctifs dans le noyau, et vous devriez maintenant pouvoir le faire (assurez-vous de récupérer la dernière version du noyau).

Ainsi, si vous avez deux images dans votre thème ou composant de thème, avec des variables SCSS $bg-light et $bg-dark respectivement, vous pouvez ajouter ceci à votre feuille de style color_definitions.scss :


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

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

Ensuite, vous pouvez utiliser var(--custom-bg) dans votre feuille de style habituelle.

8 « J'aime »

Pour une image, tout ce dont vous avez besoin est la requête média CSS vanilla prefers-dark-theme.

Cela ne fonctionnera pas correctement dans tous les cas, car la requête média ne tient pas compte des préférences de l’utilisateur. Les utilisateurs peuvent désactiver le basculement automatique du mode sombre, mais la requête média n’en sera pas informée, ce qui entraînera l’affichage de l’arrière-plan destiné au schéma de couleurs sombre.

4 « J'aime »

Est-il possible pour Discourse d’ajouter également une classe CSS à la balise <body> pour le schéma de couleurs ou l’ID du schéma de couleurs ? Cela semble beaucoup plus facile.

J’essaie de résoudre un problème lors de la conversion d’un thème où j’ai besoin de nombreuses règles CSS et variables différentes, et cela se transforme en un désordre complexe dans le fichier color_definitions.scss.

Si je pouvais simplement faire quelque chose comme ceci dans un fichier SCSS isolé dans le thème, cela prendrait 5 minutes pour faire quelque chose qui prend beaucoup de temps à comprendre avec color_definitions.scss :

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

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

Oui, vous pouvez vous retrouver avec de nombreuses lignes de code dans les fichiers de définition de couleurs, en particulier pour les dégradés.

C’est toujours l’endroit le plus approprié à mon avis. C’est loin de l’élément où il est utilisé, oui, mais c’est un endroit unique et pratique qui gère les couleurs/dégradés qui changent en fonction du mode clair/sombre.

Une alternative consiste à utiliser quelque chose comme ceci :

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

Nos schémas de couleurs sont livrés avec une propriété --scheme-type qui est light pour les schémas clairs et dark pour les schémas sombres. Les navigateurs récents prennent en charge les requêtes de conteneur, donc cela devrait faire ce que vous essayez d’accomplir ici sans ajouter une classe au corps de la page.

Mes compétences en CSS/SCSS ne sont pas excellentes. C’est peut-être plus facile pour les personnes qui sont très familières avec ces langages.

Cela causait des problèmes dans le fichier color_definitions.scss, alors je l’ai déplacé dans un autre fichier dans scss/ pour pouvoir l’importer. Je ne suis pas sûr de comment nommer tout cela, donc ça ressemble à ça.

Je pense que ce serait plus facile à faire avec une classe body (ou peut-être quelques exemples supplémentaires), mais en tout cas, ça fonctionne pour le moment. Je ne sais pas comment fonctionnent les requêtes de conteneur, mais je ferai des recherches plus tard.

Notez que les requêtes de style pour les propriétés personnalisées ne fonctionnent pas sur Firefox à la date d’aujourd’hui (14/11/2025).