在一次,介绍一个主题的内容, 如果你是前端开发者或者从其他语言转来,你会发现 Sciter 只需要使用你熟悉的 Web 技术(HTML, CSS, JavaScript)来构建原生桌面应用界面。但有一些东西和普通的浏览器应用不太一样,现在讲讲桌面软件主题定制这个部分。
1. 什么是主题(Theme)?
在 GUI 应用中,主题指的是一套视觉样式规则,它定义了应用的外观,包括颜色、字体、边框、背景等等。良好的主题系统能让应用适应不同的用户偏好(如亮色/暗色模式)或操作系统设置。简单来讲,就是主题长什么样,白天晚上显示成什么样,怎么样跟系统主题保持一致或变化。
Sciter 利用 CSS 来实现强大的主题定制能力。
2. 核心概念
a. CSS 变量 (Custom Properties)
这是现代 CSS 中实现主题的核心机制。你可以定义全局或局部的 CSS 变量来存储颜色、字体大小等值,然后在整个样式表中使用它们。切换主题通常只需要改变这些变量的值。
示例 (假设在 CSS 文件中,或 html 文件本身当中):
css
/* 定义亮色主题变量 */
:root {
--background-color: #ffffff;
--text-color: #333333;
--accent-color: #007bff;
}
/* 定义暗色主题变量 (通过属性选择器切换) */
html[theme="dark"] {
--background-color: #222222;
--text-color: #eeeeee;
--accent-color: #58a6ff;
}
/* 使用变量 */
body {
background-color: var(--background-color);
color: var(--text-color);
}
button {
background-color: var(--accent-color);
color: var(--background-color);
}
b. 使用 HTML 属性切换主题
通常,我们会通过在顶层元素(如<html>
或<body>
)上设置一个特定属性(例如theme="dark"
)来激活不同的主题规则。
示例 (JavaScript):
在usciter/res/default.js
中,你可以看到类似的代码来切换主题:
javascript
// 'theme' 是一个包含主题设置的对象, 例如 { ambience: "dark", ... }
function setupTheme(params) {
// ... 更新 theme 对象 ...
// 将当前主题模式(如 'light' 或 'dark')应用为 <html> 元素的 'theme' 属性
document.attributes["theme"] = theme.ambience;
// ... 其他设置 ...
}
对应的 CSS 就可以像上面例子那样使用html[theme="dark"] { ... }
来定义暗色模式下的样式。
c. 亮色/暗色模式 (Light/Dark Mode)
这是最常见的主题变体。通常通过切换 CSS 变量或应用不同的 CSS 类/属性来实现。
d. 系统主题集成
Sciter 可以检测操作系统的偏好设置(如 Windows 或 macOS 的暗色模式)。
如下展示了如何获取系统设置并应用:
javascript
function setupTheme(params, force) {
// ...
const newTheme = Object.assign({}, theme, params);
// 如果启用了 'useSystemAmbience'
if (newTheme.useSystemAmbience) {
// 从 Sciter 获取当前系统的 'ambience' (可能是 'light' 或 'dark')
newTheme.ambience = Window.this.mediaVar("ui-ambience");
}
// ... 应用主题 ...
}
// 监听系统主题变化事件
Window.this.on("mediachange", function() {
if (theme.useSystemAmbience)
setupTheme({ambience: Window.this.mediaVar("ui-ambience")}, true);
});
Window.this.mediaVar("ui-ambience")
会返回当前操作系统的模式。
e. 特殊效果 (如 BlurBehind)
Sciter 还支持一些与主题相关的窗口效果,比如blurBehind
(窗口背景模糊)。这通常也与主题状态(亮/暗)相关联。
javascript
// 根据主题设置启用或禁用 blurBehind
Window.this.blurBehind = theme.blurBehind ? (theme.ambience + " source-desktop") : "none";
3. 实现步骤概览
-
定义主题状态
在 JavaScript 中维护一个对象来存储当前的主题设置(如
light
/dark
, 是否启用blurBehind
, 是否跟随系统)。javascriptlet theme = { ambience: "light", // 'light' or 'dark' blurBehind: false, useSystemAmbience: true, };
-
创建应用函数
编写一个函数(如
setupTheme
)来根据主题状态对象更新界面。这包括:- 设置
<html>
或<body>
的theme
属性。 - 更新窗口效果(如
blurBehind
)。 - 更新控制主题切换的 UI 元素(如按钮)的状态。
- 设置
-
编写 CSS: 使用 CSS 变量和属性选择器 (
html[theme="dark"]
) 来定义不同主题下的样式。 -
添加用户控件: 提供按钮或其他控件让用户可以手动切换主题。在这些控件的事件处理函数中调用你的主题应用函数 (
setupTheme
)。 -
监听系统变化: 使用
Window.this.on("mediachange", ...)
来响应操作系统主题的变化,并自动更新应用主题(如果用户选择了跟随系统)。
4. 最佳实践
- 优先使用 CSS 变量: 将所有颜色、字体、间距等可变样式放入 CSS 变量中,方便集中管理和切换。
- 结构化 CSS: 将主题相关的 CSS 规则组织在一起,可以使用单独的文件或特定的注释块。
- 提供选择: 允许用户手动选择主题(亮/暗/其他),并提供"跟随系统"的选项。