Glance 主题系统完全指南:内置配色预设、HSL 颜色配置与主题切换原理
2026/9/10 11:35:05 网站建设 项目流程

Glance 主题系统完全指南:内置配色预设、HSL 颜色配置与主题切换原理

【免费下载链接】glanceA self-hosted dashboard that puts all your feeds in one place项目地址: https://gitcode.com/GitHub_Trending/gla/glance

Glance 是一款自托管的信息聚合面板,其主题能力建立在「配置文件中声明式地定义 HSL 颜色变量」这一核心机制之上。docs/themes.md 收录了官方内置的全部 15 套配色预设(11 套深色、3 套浅色),每一套都可以直接复制进glance.yml使用,也可以作为你打造自定义外观的起点。读完本文,你将掌握主题配置中每个字段的含义与取值约束、深色/浅色两套预设体系、自定义主题的接入方法,以及「配置生成 CSS 变量 → 页面热更新 → 前端实时切换」的底层实现链路。

一、主题配置:在顶层theme:块中声明

Glance 的主题全部写在配置文件的顶层theme:节点下。它不是一个独立系统,而是与pageswidgets同一层级的配置结构,因此修改主题和修改布局、挂载小组件完全一致,统一走 YAML 配置热加载。

以文档中「Teal City」这一套深色主题为例,最小配置块如下:

theme: background-color: 225 14 15 primary-color: 157 47 65 contrast-multiplier: 1.1

与多数面板“直接填十六进制色值”不同,Glance 主题的全部颜色字段都采用空格分隔的 HSL 三元组H S L),而不是#RRGGBB。这样做的工程意义在于:整个界面的文字、分割线、进度条、弹层背景等大量衍生色,都围绕同一色相做亮度/饱和度偏移生成,只要换一个背景色相,整套 UI 就能在视觉上保持统一(见 internal/glance/static/css/main.css 中基于--bgh/--bgs/--bgl的大量hsl(var(--bghs), ...)派生计算)。

全部可用字段

字段类型含义取值范围/说明
background-colorHSL页面主背景色H:0–360;S、L:0–100
primary-colorHSL主强调色(链接、按钮、边框、选中态等)同上
positive-colorHSL正向语义色(上升、在线、成功等)同上
negative-colorHSL负向语义色(下降、错误、告警等)同上
lightbool声明为浅色主题影响data-scheme与配色推导方向
contrast-multiplierfloat文字对比度倍率内置预设使用 1.0–1.5
text-saturation-multiplierfloat文字饱和度倍率内置预设中为 0.5,用于压制亮色背景上的文字饱和度

这些字段直接对应源码中 internal/glance/theme.go 的themeProperties结构体,YAML tag 与上表字段一一对应。颜色值在解析时经过严格校验:hslColorField.UnmarshalYAML通过正则解析三元组,并逐一检查hue ≤ 360saturation ≤ 100lightness ≤ 100,越界会给出包含具体 YAML 行号的报错(见 internal/glance/config-fields.go)。正则也兼容hsla(...)包裹或逗号分隔的写法,但官方预设统一使用纯数字空格分隔。

字段是如何变成样式的

每个主题块在初始化时,都会被丢进模板 internal/glance/templates/theme-style.gotmpl,动态生成一段 CSS 变量声明(只输出配置过的字段):

:root { --bgh: 225; --bgs: 14%; --bgl: 15%; --cm: 1.1; --color-primary: hsl(157.0, 47.0%, 65.0%); --color-positive: ...; --color-negative: ...; }

这段 CSS 由 internal/glance/theme.go 的themeProperties.init()渲染,随后被内联到每个页面的<style id="theme-style">标签中(见 internal/glance/templates/document.html)。background-color还会被转换成十六进制,用于浏览器地址栏的theme-colormeta 与 PWA 清单中的应用背景色。

二、深色主题预设(Dark)

以下 11 套深色预设均直接取自 docs/themes.md,配合文档目录 docs/images/themes/ 中的官方截图使用。

Teal City

theme: background-color: 225 14 15 primary-color: 157 47 65 contrast-multiplier: 1.1

Catppuccin Frappe

theme: background-color: 229 19 23 contrast-multiplier: 1.2 primary-color: 222 74 74 positive-color: 96 44 68 negative-color: 359 68 71

Catppuccin Macchiato

theme: background-color: 232 23 18 contrast-multiplier: 1.2 primary-color: 220 83 75 positive-color: 105 48 72 negative-color: 351 74 73

Catppuccin Mocha

theme: background-color: 240 21 15 contrast-multiplier: 1.2 primary-color: 217 92 83 positive-color: 115 54 76 negative-color: 347 70 65

Camouflage

theme: background-color: 186 21 20 contrast-multiplier: 1.2 primary-color: 97 13 80

Gruvbox Dark

theme: background-color: 0 0 16 primary-color: 43 59 81 positive-color: 61 66 44 negative-color: 6 96 59

Kanagawa Dark

theme: background-color: 240 13 14 primary-color: 51 33 68 negative-color: 358 100 68 contrast-multiplier: 1.2

Tucan

theme: background-color: 50 1 6 primary-color: 24 97 58 negative-color: 209 88 54

Dracula

theme: background-color: 231 15 21 primary-color: 265 89 79 contrast-multiplier: 1.2 positive-color: 135 94 66 negative-color: 0 100 67

Shades of Purple

theme: background-color: 243 33 25 contrast-multiplier: 1.2 primary-color: 50 100 49 positive-color: 98 82 71 negative-color: 12 77 52

Neon Pink

theme: background-color: 240 27 11 contrast-multiplier: 1.5 primary-color: 321 100 71 positive-color: 165 78 51 negative-color: 360 100 71

三、浅色主题预设(Light)

浅色预设与深色预设的结构完全一致,唯一的差别是必须显式声明light: true。该标志会直接影响渲染结果:HTML 根节点的data-scheme属性会被标记为light,CSS 中大量calc(var(--scheme) ...)推导式的运算方向也会随之反转,从而在浅色背景下自动生成对比度足够的深色文字,而不必逐项手工指定文字颜色。

Catppuccin Latte

theme: light: true background-color: 220 23 95 contrast-multiplier: 1.0 primary-color: 220 91 54 positive-color: 109 58 40 negative-color: 347 87 44

Peachy

theme: light: true background-color: 28 40 77 primary-color: 155 100 20 negative-color: 0 100 60 contrast-multiplier: 1.1 text-saturation-multiplier: 0.5

注意 Peachy 额外使用了text-saturation-multiplier: 0.5:在低饱和度的粉色背景上,如果文字继续沿用背景的相近色相,会显得刺眼、难读,因此把文字饱和度压缩一半。这与内置的浅色默认主题行为一致——text-saturation-multiplier的默认生效值正是 0.5(见下文源码分析)。

Zebra

theme: light: true background-color: 0 0 95 primary-color: 0 0 10 negative-color: 0 90 50

四、从源码看主题的默认值与双主题机制

你没写颜色时会发生什么

themeProperties.init()中有一个重要兜底逻辑:当整个theme:块完全为空时,BackgroundColorAsHex会被设置为#151519(见 internal/glance/theme.go),保证没有任何主题配置也能渲染出可用的深色外观。而在 YAML 层,颜色字段全部是指针类型、默认nil,模板只有在字段非空时才会输出对应的 CSS 变量——这正是“最小主题块只需写三个字段”也能正常运行的原因。

default-dark 与 default-light

Glance 的“默认主题”概念是成对出现的。在应用初始化阶段(internal/glance/glance.go),只要未关闭主题选择器,就会向内部预设集合注入两套兜底主题:

  • default-dark:完全空白配置(themeProperties{}),即依赖上文#151519兜底与 CSS 默认色;
  • default-light:硬编码的浅色默认主题,背景240 13 95、主色230 100 30、负向色0 70 50contrast-multiplier: 1.3text-saturation-multiplier: 0.5

随后,你在顶层theme:块中写的颜色,会成为页面无 Cookie 状态下的“默认”外观;而default-dark/default-light这两套只出现在前端主题切换器里。如果你的顶层theme:恰好与其中某套完全相同,初始化代码会跳过重复注入,避免切换器中出现两个看起来一样的选项。

运行时切换主题:Cookie + 专用路由

Glance 允许访问者在不改动配置的前提下临时切换外观。其实现要点如下:

  1. 页面加载时,internal/glance/glance.go 的populateTemplateRequestData会读取名为theme的 Cookie,命中内部预设集合中的某个键后,就用该预设替换当前渲染主题;
  2. 主题切换器(页面右上角的下拉控件,见 internal/glance/templates/page.html)的每个选项都调用POST /api/set-theme/{key}接口,路由注册于 internal/glance/glance.go;
  3. internal/glance/theme.go 的handleThemeChangeRequest会先校验key是否存在于预设集合中(default键则映射回配置主块),随后写回有效期 2 年的 Cookie,并直接把该预设的 CSS 作为text/css响应体返回,同时通过X-Scheme响应头声明明暗属性,前端拿到后即可完成无刷新换肤。

presets:为切换器注册你自己的主题

theme:块还支持一个presets映射,用于把多套主题同时注册进右上角的主题切换器。该结构在 internal/glance/config.go 中声明,类型为保序的 YAML 映射(orderedYAMLMap,实现见同文件 internal/glance/config.go),并在初始化时与内置的 default 系列合并。每套预设与顶层主题拥有完全相同的字段。例如:

theme: background-color: 231 15 21 # 作为默认主题 primary-color: 265 89 79 presets: my-dark: background-color: 250 40 10 primary-color: 20 90 55 contrast-multiplier: 1.3 my-light: light: true background-color: 220 30 90 primary-color: 220 80 45

保存配置后,切换器(其渲染模板见 internal/glance/templates/theme-preset-preview.html,会为每套预设生成一个带主色/正负语义色圆点的小色卡预览)就会出现my-darkmy-light两个可点击项。

何时关闭主题切换器与追加自定义 CSS

theme:块还有两个配套字段:

  • disable-picker: true:关闭右上角的主题选择器,也意味着不注入 default-dark/default-light 预设(代码见 internal/glance/glance.go),且 Cookie 换肤逻辑整体失效,所有人看到的都是顶层theme:的外观;
  • custom-css-file:指向一个 CSS 文件的路径,该文件的全部内容会作为页面额外的<style>注入,用来在主题变量之外追加更细粒度的定制样式。

五、把一套预设真正跑起来

官方预设已经保证了开箱即用,实践中有三种用法:

  1. 整块替换:把上面任一 YAML 块整体放进glance.yml,替换掉已有的theme:内容,刷新页面即生效;
  2. 只改局部:保留自己的theme:,仅借鉴某套预设中的单个字段值,例如把 Teal City 的contrast-multiplier: 1.1复制到自己的主题上增强文字对比;
  3. 注册进切换器:用上文的presets语法同时注册多套官方配色,让访问者随时切换。

想进一步查看这些预设当前生效效果的完整截图,可打开文档目录 docs/images/themes/ 下的同名图片逐一对照;配置文件的整体结构示例见仓库根目录的 docs/glance.yml,关于全部顶层配置项(含theme)的说明可继续阅读 docs/configuration.md。

六、小结:主题即配置,换肤即换 CSS 变量

总结 Glance 主题系统的完整工作链条:theme:YAML →themeProperties结构体解析与 HSL 数值校验 → theme-style.gotmpl 渲染出:rootCSS 变量 → 内联进 document.html 的<style id="theme-style">→ 交由 main.css 中基于色相派生的大量子规则完成整页配色;同时通过「Cookie +POST /api/set-theme/{key}+ presets 预设集合」支撑起前端实时换肤。

对使用者而言,掌握了docs/themes.md里的全部字段与 15 套官方预设,就等于掌握了给 Glance 换装的全部素材;对想要深度定制的人来说,官方预设中那些“只写了 3–4 个颜色就能得到完整精致 UI”的配置,恰恰是理解其同色相派生配色引擎的最好范本。

【免费下载链接】glanceA self-hosted dashboard that puts all your feeds in one place项目地址: https://gitcode.com/GitHub_Trending/gla/glance

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询