所以你对设计自己的 Discourse 主题感兴趣?你来对地方了 ![]()
本指南将更侧重于在 Discourse 中处理主题时的 SCSS/CSS 方面。如果你也熟悉 JS/EmberJs/Handlebars,可以通过查看此指南深入了解更多内容。
我将向你介绍我在 Discourse 中设计和创建主题的个人方法。和大多数事情一样,实现你自己设计的方法有很多种。我在创建主题时喜欢大量使用检查器工具,并将在本帖子中展示几次我是如何做到的。
主题设计设置
在继续之前,请阅读 Discourse 主题使用入门指南 以及 主题结构…。此时不需要深入的知识,但这些文章会让你在开始之前对主题有更熟悉的了解。
为了最好地在 Discourse 中进行主题设计,我建议进行以下设置,以提供最快、最流畅的设计流程。这些步骤将使你无需从 Discourse 站点管理面板“保存”并刷新即可看到所做的更改。
完全可以通过管理控制台(前提是你拥有 Discourse 论坛的管理员级别访问权限)来完成本指南的内容。
- 安装 Discourse Theme CLI 并阅读该主题以了解其功能。
- 从 https://discourse.theme-creator.io/ 获取 API 密钥
- 使用你的 Meta 账户登录
- 点击 我的主题
- 点击 API 密钥
- 在弹出的模态框中,点击 生成 API 密钥 并复制为你生成的密钥(我们稍后会用到它)
运行 Discourse Theme CLI
安装 Discourse Theme CLI 并准备好 API 密钥后,打开你首选的文本编辑器或终端窗口,并将工作目录更改到你希望设置主题文件夹的位置。
到达该位置后,运行以下命令 discourse_theme new your_theme_name 并按照以下提示填写:
-
你想给你的主题起什么名字? 选择你的主题名称
-
你想开始监视这个主题吗? 是
-
你的 Discourse 站点的根 URL 是什么?
https://discourse.theme-creator.io/ -
你想将此站点名称存储在…吗? 是
-
你的 API 密钥是什么? 输入你从 theme creator 获取的 API 密钥
-
你想将此 API 密钥存储在…吗? 是
-
当被提示时,选择 创建并与新主题同步
-
当被问及子主题组件时,选择 不执行任何操作
如果一切正常,你现在应该能够访问 https://discourse.theme-creator.io/ 上的 My Themes,并在左侧的主题列表中看到你的新主题。
要实时查看这些更改,点击你的主题名称,然后在信息区域底部点击 预览
Theme CLI 现在也在监视新创建的目录中的任何更改,并会在每次更改时保存并更新 theme-creator 上的主题。
第一步
Discourse Theme CLI 在我们之前运行命令时指定的文件夹名称内为我们创建了一个主题脚手架。生成了许多我们不会使用的文件,所以我们将删除除以下内容之外的所有内容:
common/common.scss
desktop/desktop.scss
mobile/mobile.scss
about.json
在目录内,也运行 rm -rf .git 以删除 git 版本跟踪,本指南不需要它。
你的主题目录现在应该看起来像这样:
值得注意的是,我们添加到这些文件中的样式将在其各自的使用场景中渲染。common.scss 中的样式将应用于桌面 + 移动设备,而 desktop.scss 中的样式仅应用于桌面浏览,mobile.scss 中的样式仅应用于移动视图。
Hello World(带颜色)
Discourse 使用 SCSS 进行样式设置,因此为了最好地利用样式,你可能需要熟悉 SASS,但如果不熟悉,你仍然可以跟随本指南。
好了,现在让我们进入大家一直等待的内容… 主题设计!
目前,我们的 about.json 没有定义任何 color_schemes,因此将以下代码粘贴到该部分然后保存。
{
"name": "my theme",
"about_url": null,
"license_url": null,
"assets": {},
"color_schemes": {
"Default": {
"primary": "222222",
"secondary": "ffffff",
"tertiary": "0088cc",
"quaternary": "e45735",
"header_background": "ffffff",
"header_primary": "333333",
"highlight": "ffff4d",
"danger": "e45735",
"success": "009900",
"love": "fa6c8d"
}
}
}
如果你打开了浏览器,你不会看到任何更改生效,因为这是在不存在方案时使用的默认颜色方案。
主题概览
为了在本指南中实际实现一些内容,我将指导你创建一个基于此调色板的简单主题。

更改背景颜色 + 主要文本颜色
让我们做一件非常简单的事情。我们将更改当前颜色方案的 "Secondary" 值。让我们将其更改为 "secondary": "EEF4F7"(这会更改背景颜色。)让我们也将 "primary" 值更改为 "203243"。
仅凭这一行,我们已经改变了论坛的外观和感觉。仅通过编辑颜色方案中的颜色就可以进行大量的自定义。
颜色方案的使用
以下所有键都在 about.json 文件中对应的颜色方案名称下定义。这些描述是一个很好的参考,帮助你理解每个变量名称的主要用途:
| 颜色 | 描述 |
|---|---|
| primary | 大多数文本、图标和边框 |
| secondary | 主要背景颜色,以及某些按钮的文本颜色 |
| tertiary | 链接、某些按钮、通知和强调色 |
| quaternary | 导航链接 |
| header_background | 站点标题的背景颜色 |
| header_primary | 站点标题中的文本和图标 |
| highlight | 页面上突出显示元素(如帖子和主题)的背景颜色 |
| danger | 删除帖子和主题等操作的高亮颜色 |
| success | 用于指示操作成功 |
| love | 点赞按钮的颜色 |
我们可以像在 SCSS 文件中使用以下变量一样使用这些变量。
body {
background-color: var(--primary);
}
还为每个颜色生成了其他版本供我们使用。像 var(--primary-medium) 或 var(--primary-very-low) 这样的东西可以用来获取相同颜色的不同色调。
让我们将 “Default” 颜色方案中的其他颜色更改为与此匹配:
"Default": {
"primary": "203243",
"secondary": "EEF4F7",
"tertiary": "416376",
"quaternary": "5E99B9",
"header_background": "FaFaFa",
"header_primary": "EEF4F7",
"highlight": "86BDDB",
"danger": "8F393E",
"success": "70DB82",
"love": "FC94CB"
}
如果你在 theme creator 上预览主题时点击 样式指南 链接,然后点击左侧菜单中的 Colors,你可以看到所有可用于 SCSS 文件的变量。
样式指南是在创建自定义主题时非常值得查看的部分。每个 Atom 都会向你展示 Discourse 的某些元素在应用你的样式后的外观。
深入探索
有了上一节的基础,我认为是时候深入探讨一下仅使用 SCSS 在 Discourse 中可以做些什么了。(提示:很多!)
样式化标题
你会注意到,我们对颜色方案的先前更改使我们的标题有些不尽如人意。图标几乎看不见!
![]()
Discourse 标题包含一个容器(带有背景颜色),用于容纳站点标志以及右侧的导航图标。所有这些都可以自定义。
自定义标题的目标类是 .d-header。
在我们的 common/common.scss 文件中,让我们添加以下内容:
.d-header {
box-shadow: none;
border-bottom: 1px solid var(--primary-low-mid);
height: 5em;
}
这将移除标题上默认的 box-shadow,增加一点高度,并设置 border-bottom 以提供一些分隔。
对于图标 – 在 .d-header SCSS 括号内,让我们添加以下嵌套代码。
.d-header {
// ...previous code
.d-icon {
color: var(--primary-low-mid);
}
}
这看起来不错,但敏锐的眼睛会注意到增加的标题高度使得它与 Discourse 论坛其余元素之间的空间变小了!
主区域和标题之间的间距由 #main-outlet 目标控制。让我们通过向 common/common.scss 文件底部添加以下内容来稍微增加这个间距。
#main-outlet {
padding-top: 6.5em;
}
导航容器
导航容器包含以下部分。
![]()
最左侧区域是类别/标签过滤下拉菜单,接着是导航链接,以新主题按钮结束。
类别 / 标签下拉菜单
让我们对这个区域进行一些更改。为此,将以下内容添加到你的 common.scss 文件中。
.navigation-container {
.select-kit.combo-box {
.select-kit-header {
border-radius: 0.9em;
background-color: var(--header_background);
}
}
}
这里我们针对 .select-kit-header 为它们每个提供相同的 border-radius,以及更浅的背景颜色。
点击其中任何一个,会打开一个下拉菜单。
目前,它也有硬角,所以让我们添加一些样式来圆角化这些,并将背景颜色更改为与标题相同。
.navigation-container {
.select-kit.combo-box {
// ...previous code
&.category-drop,
&.tag-drop {
.select-kit-body {
border-radius: 0.9em;
background-color: var(--header_background);
.select-kit-collection {
background-color: var(--header_background);
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
}
}
}
}
这会产生以下外观…
如果你仔细看,可以看到我们的更改在搜索区域的右上角留下了一条小边框。
让我们通过查看浏览器的检查器来修复这个问题。这是一个非常有用的工具,可以学习我们需要针对哪些类/ID 才能正确应用样式。
在下拉菜单可见时,右键点击搜索区域并在浏览器中“检查”该元素。
我们可以看到这个输入位于一个类为 select-kit-filter 的 div 内。
如果我们查看应用于此选择器的规则,我们可以看到它目前具有 border-top 和 bottom,以及一些应用的 padding。我们只想更改 border-top 样式。
将以下代码嵌套在之前的 .select-kit-body scss 中。
.select-kit.combo-box.category-drop,
.select-kit.combo-box.tag-drop {
.select-kit-body {
// ...previous code
.select-kit-filter {
border-top: 0px;
}
}
}
这样,我们用于样式化导航容器的代码应该看起来像这样。
.navigation-container {
// Category + Tag Drop Down
.select-kit.combo-box {
.select-kit-header {
border-radius: 0.9em;
background-color: var(--header_background);
}
&.category-drop,
&.tag-drop {
.select-kit-body {
border-radius: 0.9em;
background-color: var(--header_background);
.select-kit-collection {
background-color: var(--header_background);
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
.select-kit-filter {
border-top: 0px;
}
}
}
}
}
导航链接
让我们添加一些样式,使这些导航链接看起来类似于这样:
![]()
让我们再次使用检查器来发现我们应该在这里针对什么。
我们可以看到我们的导航元素位于一个类为 "nav nav-pills ..." 的 UL 内。
回到我们的 common.scss 文件,在上一节下方,但仍然嵌套在 navigation-container 内,让我们添加以下内容:
.nav-pills {
& > li a {
&.active {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--tertiary);
}
}
}
此更改将仅针对类为 active 且为 nav-pills 子元素的链接。此更改应使我们的活动链接看起来像这样:
![]()
这没问题,但我希望底部边框仅延伸到文本的范围。为此,在 &.active { 行上方,让我们添加以下内容,这将影响导航 <li> 标签内的所有 A 链接。
// ...other code
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
// ...more code
}
}
}
现在,我们需要将“悬停”效果样式化为与“活动”效果相同。
在我们之前的 &.active 下方,让我们添加
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
因此,我们所有的导航代码现在应该看起来像这样:
// Nav Pills
.nav-pills {
& > li a {
padding: 0;
margin-right: 20px;
color: var(--tertiary-high);
border-bottom: 4px solid transparent;
&.active {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--tertiary);
}
&:hover {
color: var(--tertiary);
background-color: var(--secondary);
border-bottom: 4px solid var(--primary);
}
}
}
按钮
Discourse 中的按钮有多种形状和大小。你可以在样式指南的按钮部分查看各种按钮。
我希望将此主题上的大多数按钮更改为带有自定义样式的圆角按钮。这将更改 + 新主题 按钮,以及站点上的其他按钮。
在我们的 common.scss 文件底部,让我们添加以下内容:
.btn {
background-color: var(--header_background);
color: var(--primary);
border-radius: 1.2em;
border: 1px solid var(--primary-low-mid);
.d-icon {
color: var(--primary);
}
&:hover {
background-color: var(--quaternary-low);
color: var(--primary);
.d-icon {
color: var(--primary);
}
}
&.btn-default,
&.btn-primary {
padding: 10px 12px;
}
}
这将使我们的按钮看起来像这样:

现在我们的按钮已经样式化了,我想指出关于按钮样式化以及为什么测试所有设计很重要的一点。
点击你的站点预览中的一个主题,然后点击主题回复上的 回复 按钮,或从主题流底部的回复按钮。你会看到我们的按钮样式影响了一些我们可能没有想到的东西。
我不希望这些文本编辑按钮受到我先前样式化的影响。这需要更复杂的 SASS/CSS,但我们可以让代码使用 :not() 来不影响这些按钮。![]()
让我们在当前 .btn 目标前面添加这行代码。这将告诉我们的样式仅应用于不是 .d-editor-button-bar 子元素的按钮。
:not(.d-editor-button-bar) > .btn
好的,那工作得很好……但是等等!现在有一个奇怪的叛逆者在做它自己的事情。
![]()
在浏览器中检查这个,我可以看到这个按钮有一个类 .select-kit-header,因为点击这个齿轮会显示更多选项。
我无法强调在创建 Discourse 主题时使用浏览器检查器工具的重要性。它们是你在这一旅程中最好的伙伴。
现在我们知道我们 不想 针对这个按钮,让我们向我们的代码添加更多 :not() 功能。
:not(.d-editor-button-bar) >
.btn:not(.single-select-header)
这将选择所有不是 .d-editor-button-bar 子元素且没有类 .single-select-header 的按钮。我知道这有点令人困惑,但在 Discourse 内部,有很多活动部件,因此有时样式需要非常具体才能正确影响元素。
我还注意到我们当前的样式奇怪地影响了模态关闭按钮。点击任何弹出模态框的东西都会让你看到这一点,或者更简单的是,我们可以导航到样式指南的模态框部分。
为了修复这个问题,我将向我们的代码添加另一个目标。
:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close)
继续…
我看到还有一个按钮似乎没有受到我们代码的影响。它是位于主题帖子流最底部的 跟踪 按钮。

我将在当前 .btn 代码中,逗号后添加以下行。
:not(.d-editor-button-bar) >
.btn:not(.single-select-header):not(.modal-close),
.topic-notifications-button > .select-kit > .btn
这将正确针对出现在此部分的按钮,目前,我们完成了论坛顶部区域的样式化。
请随意调整你 css 中的任何参数。你越多地摆弄这些样式并查看它们如何以及影响 html,你将学到越多!
接下来去哪里
本指南旨在介绍如何自定义你自己的 Discourse 主题的表面。我希望你现在对如何针对应用程序的某些区域进行自定义有更多的见解。
记住 仅使用 SCSS 就可以自定义很多东西。如果你想更深入地开发,我建议你阅读本帖子顶部链接的文章。
请随时提出任何问题,我很乐意尝试帮助你,或指引你正确的方向。
本文档受版本控制 - 在 github 上建议更改。










