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

发布时间:2026/9/10 11:35:13
Glance 主题系统完全指南:内置配色预设、HSL 颜色配置与主题切换原理 Glance 主题系统完全指南内置配色预设、HSL 颜色配置与主题切换原理【免费下载链接】glanceA self-hosted dashboard that puts all your feeds in one place项目地址: https://gitcode.com/GitHub_Trending/gla/glanceGlance 是一款自托管的信息聚合面板其主题能力建立在「配置文件中声明式地定义 HSL 颜色变量」这一核心机制之上。docs/themes.md 收录了官方内置的全部 15 套配色预设11 套深色、3 套浅色每一套都可以直接复制进glance.yml使用也可以作为你打造自定义外观的起点。读完本文你将掌握主题配置中每个字段的含义与取值约束、深色/浅色两套预设体系、自定义主题的接入方法以及「配置生成 CSS 变量 → 页面热更新 → 前端实时切换」的底层实现链路。一、主题配置在顶层theme:块中声明Glance 的主题全部写在配置文件的顶层theme:节点下。它不是一个独立系统而是与pages、widgets同一层级的配置结构因此修改主题和修改布局、挂载小组件完全一致统一走 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页面主背景色H0–360S、L0–100primary-colorHSL主强调色链接、按钮、边框、选中态等同上positive-colorHSL正向语义色上升、在线、成功等同上negative-colorHSL负向语义色下降、错误、告警等同上lightbool声明为浅色主题影响data-scheme与配色推导方向contrast-multiplierfloat文字对比度倍率内置预设使用 1.0–1.5text-saturation-multiplierfloat文字饱和度倍率内置预设中为 0.5用于压制亮色背景上的文字饱和度这些字段直接对应源码中 internal/glance/theme.go 的themeProperties结构体YAML tag 与上表字段一一对应。颜色值在解析时经过严格校验hslColorField.UnmarshalYAML通过正则解析三元组并逐一检查hue ≤ 360、saturation ≤ 100、lightness ≤ 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 idtheme-style标签中见 internal/glance/templates/document.html。background-color还会被转换成十六进制用于浏览器地址栏的theme-colormeta 与 PWA 清单中的应用背景色。二、深色主题预设Dark以下 11 套深色预设均直接取自 docs/themes.md配合文档目录 docs/images/themes/ 中的官方截图使用。Teal Citytheme: background-color: 225 14 15 primary-color: 157 47 65 contrast-multiplier: 1.1Catppuccin Frappetheme: background-color: 229 19 23 contrast-multiplier: 1.2 primary-color: 222 74 74 positive-color: 96 44 68 negative-color: 359 68 71Catppuccin Macchiatotheme: background-color: 232 23 18 contrast-multiplier: 1.2 primary-color: 220 83 75 positive-color: 105 48 72 negative-color: 351 74 73Catppuccin Mochatheme: background-color: 240 21 15 contrast-multiplier: 1.2 primary-color: 217 92 83 positive-color: 115 54 76 negative-color: 347 70 65Camouflagetheme: background-color: 186 21 20 contrast-multiplier: 1.2 primary-color: 97 13 80Gruvbox Darktheme: background-color: 0 0 16 primary-color: 43 59 81 positive-color: 61 66 44 negative-color: 6 96 59Kanagawa Darktheme: background-color: 240 13 14 primary-color: 51 33 68 negative-color: 358 100 68 contrast-multiplier: 1.2Tucantheme: background-color: 50 1 6 primary-color: 24 97 58 negative-color: 209 88 54Draculatheme: background-color: 231 15 21 primary-color: 265 89 79 contrast-multiplier: 1.2 positive-color: 135 94 66 negative-color: 0 100 67Shades of Purpletheme: background-color: 243 33 25 contrast-multiplier: 1.2 primary-color: 50 100 49 positive-color: 98 82 71 negative-color: 12 77 52Neon Pinktheme: 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属性会被标记为lightCSS 中大量calc(var(--scheme) ...)推导式的运算方向也会随之反转从而在浅色背景下自动生成对比度足够的深色文字而不必逐项手工指定文字颜色。Catppuccin Lattetheme: 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 44Peachytheme: 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见下文源码分析。Zebratheme: 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-lightGlance 的“默认主题”概念是成对出现的。在应用初始化阶段internal/glance/glance.go只要未关闭主题选择器就会向内部预设集合注入两套兜底主题default-dark完全空白配置themeProperties{}即依赖上文#151519兜底与 CSS 默认色default-light硬编码的浅色默认主题背景240 13 95、主色230 100 30、负向色0 70 50、contrast-multiplier: 1.3、text-saturation-multiplier: 0.5。随后你在顶层theme:块中写的颜色会成为页面无 Cookie 状态下的“默认”外观而default-dark/default-light这两套只出现在前端主题切换器里。如果你的顶层theme:恰好与其中某套完全相同初始化代码会跳过重复注入避免切换器中出现两个看起来一样的选项。运行时切换主题Cookie 专用路由Glance 允许访问者在不改动配置的前提下临时切换外观。其实现要点如下页面加载时internal/glance/glance.go 的populateTemplateRequestData会读取名为theme的 Cookie命中内部预设集合中的某个键后就用该预设替换当前渲染主题主题切换器页面右上角的下拉控件见 internal/glance/templates/page.html的每个选项都调用POST /api/set-theme/{key}接口路由注册于 internal/glance/glance.gointernal/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-dark、my-light两个可点击项。何时关闭主题切换器与追加自定义 CSStheme:块还有两个配套字段disable-picker: true关闭右上角的主题选择器也意味着不注入 default-dark/default-light 预设代码见 internal/glance/glance.go且 Cookie 换肤逻辑整体失效所有人看到的都是顶层theme:的外观custom-css-file指向一个 CSS 文件的路径该文件的全部内容会作为页面额外的style注入用来在主题变量之外追加更细粒度的定制样式。五、把一套预设真正跑起来官方预设已经保证了开箱即用实践中有三种用法整块替换把上面任一 YAML 块整体放进glance.yml替换掉已有的theme:内容刷新页面即生效只改局部保留自己的theme:仅借鉴某套预设中的单个字段值例如把 Teal City 的contrast-multiplier: 1.1复制到自己的主题上增强文字对比注册进切换器用上文的presets语法同时注册多套官方配色让访问者随时切换。想进一步查看这些预设当前生效效果的完整截图可打开文档目录 docs/images/themes/ 下的同名图片逐一对照配置文件的整体结构示例见仓库根目录的 docs/glance.yml关于全部顶层配置项含theme的说明可继续阅读 docs/configuration.md。六、小结主题即配置换肤即换 CSS 变量总结 Glance 主题系统的完整工作链条theme:YAML →themeProperties结构体解析与 HSL 数值校验 → theme-style.gotmpl 渲染出:rootCSS 变量 → 内联进 document.html 的style idtheme-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),仅供参考