以前,Discourse 中的所有颜色都存储为 SCSS 变量。为了支持自动深色模式颜色方案切换,我们将核心中的这些颜色转换为自定义 CSS 属性。您现在可以在检查器中轻松查看完整列表:
主题和插件需要在样式表中使用的所有 $color SCSS 变量切换到 --color CSS 属性的等效项。在大多数情况下,这是一个简单的查找和替换任务:
- background-color: $primary-very-low;
+ background-color: var(--primary-very-low);
但有些情况下,主题或插件使用了更复杂的颜色变体,例如使用 SCSS 颜色函数进行加深或变亮。这些情况需要更复杂的重构,为此我们增加了在主题和插件中扩展颜色定义的能力。
在插件中
discourse-encrypt 插件中的此提交是一个良好且简单的重构示例。它将 mix($color1, $color2) SCSS 声明移动到一个单独的文件中,并将其存储为 CSS 自定义属性。然后,新文件被注册为 :color_definitions 资源,以确保新声明的颜色属性包含在颜色定义样式表中。
在主题中
在主题中,您可以通过在 common/color_definitions.scss 样式表中声明 CSS 自定义属性来完成相同的操作。您可以查看此 graceful 主题中的提交以获取示例。
一些额外的注意事项
- 当使用
rgba($color, 0.5) 函数通过透明颜色时,SCSS 接受 HEX 和 RGB 颜色作为第一个参数,而 CSS 自定义属性只接受 RGB 颜色。这就是我们引入 hexToRGB() 帮助函数以及一些带有 --rgb 后缀的属性的原因。一个例子:
// color_definitions.scss
:root {
--primary: #{$primary};
--primary-rgb: #{hexToRGB($primary)};
}
// other stylesheet
.element {
background-color: rgba(var(--primary-rgb), 0.05);
}
- background-color: $primary-very-low;
+ background-color: var(--primary-very-low, $primary-very-low);
本文档是版本控制的 - 在 github 上建议更改。
24 个赞
pfaffman
(Jay Pfaffman)
2
我对这些东西不太在行,要我自己弄明白还得花些时间……这是否意味着之前所有引用颜色的主题现在都会失效?
6 个赞
pmusaraj
(Penar Musaraj)
3
不,完全不会。主题中的 SCSS 变量在很长一段时间内仍将继续有效。
但通过 SCSS 变量输出的颜色将保持静态,也就是说,当浏览器从正常模式切换到暗色模式时,它们无法动态切换为新的配色方案。因此,这些主题和插件仍将继续运行,只是它们无法与自动暗色模式切换功能兼容。
13 个赞
tomtjes
(Thomas Reintjes)
4
感谢提供的说明。是否也可以根据深色/浅色模式更改背景图像?(我已使用主题切换器组件实现了这一点。)是否可以通过添加一个指示当前模式的 CSS 类来实现?
2 个赞
pmusaraj
(Penar Musaraj)
5
好问题!我尝试了一下,发现我们在特殊颜色定义样式表中未能正确支持背景图片或主题变量的使用。因此,我在核心代码中做了一些修复,现在您应该可以这样做了(请确保拉取了最新的核心代码)。
因此,如果您的主题或主题组件中有两张图片,分别对应 SCSS 变量 $bg-light 和 $bg-dark,您可以将以下内容添加到您的 color_definitions.scss 样式表中:
$bg: url(dark-light-choose($bg-light, $bg-dark));
:root {
--custom-bg: #{$bg};
}
然后,您可以在常规样式表中使用 var(--custom-bg)。
8 个赞
riking
(Kane York)
6
对于图片,您只需使用原生的 prefers-dark-theme CSS 媒体查询即可。
pmusaraj
(Penar Musaraj)
7
这在所有情况下都无法很好地工作,因为该媒体查询无法感知用户的偏好。用户可以禁用自动深色模式切换,但媒体查询无法察觉这一点,导致本应用于深色配色方案的背景被渲染出来。
4 个赞
j127
8
Discourse 是否也可以为 <body> 添加一个 CSS 类来表示配色方案或配色方案 ID?这似乎会容易得多。
我正在尝试解决主题转换中的一个问题,我需要大量的不同的 CSS 规则和变量,这在 color_definitions.scss 文件中变成了一个复杂的混乱。
如果我能在主题中的一个隔离的 SCSS 文件中做到这一点,那么用 color_definitions.scss 来解决一个需要很长时间才能弄清楚的问题,只需要 5 分钟:
body.dark-palette .some-thing {
// 一些样式
}
body.light-palette .some-thing {
// 一些样式
}
pmusaraj
(Penar Musaraj)
9
是的,您可能会在颜色定义文件中遇到许多代码行,尤其是在处理渐变时。
在我看来,这仍然是最合适的位置。它确实远离了使用它的元素,但它是一个方便的单一位置,可以处理基于浅色/深色模式切换的颜色/渐变。
另一种方法是使用类似这样的方法:
@container style(--scheme-type: light){
body{
background: red;
}
}
我们的颜色方案带有一个 --scheme-type 属性,浅色方案为 light,深色方案为 dark。最近的浏览器支持容器查询,因此这应该可以在不向页面主体添加类的情况下完成您在此处尝试完成的任务。
j127
10
我的 CSS/SCSS 技能不是很好。也许对于精通这些技术的人来说会更容易。
它弄乱了 color_definitions.scss 文件,所以我把它移到了 scss/ 中的另一个文件中,这样我就可以导入它了。我不确定该如何命名,所以它看起来是这样的。
我认为使用 body 类(或者更多示例)会更容易,但无论如何,它目前是有效的。我不知道容器查询是如何工作的,但我以后会研究它。
panic
11
请注意,截至今天(2025/11/14),Firefox 不支持 自定义属性的样式查询。