深浅主题 (Theming)
- 文章發表於
深色与浅色主题近年来几乎已成为网站的标配,从个人博客到全球级的客户端应用(例如:GitHub),皆提供深浅色主题的切换功能,让使用者能依照个人喜好自由选择界面风格。
要实现网站主题的无痛切换,我认为最重要的原则是:在开发时,以〈设计标签〉作为 CSS 参数的基石。在先前的章节〈从设计标签到 CSS〉 中,我们已介绍过其带来的好处。如果产品色码未被纳入设计标签 (Design Token) 内,就必须在应用层的 CSS 中额外处理,这在日后更改颜色时会增添不必要的麻烦。
回顾
设计标签 (Design Tokens)
在 〈设计标签〉 一文中,我们介绍了设计标签的基本概念。其中,透过 System Token(alias.json
)的深浅主题配置,分别对应到不同的 Reference Token(base.json
),这样的设计使我们能根据不同条件,动态地将同一个 System Token 解析为不同的值。
标准化 CSS (Normalized CSS)
接着,在 Style Dictionary 构建设计标签的过程中,其会将 :root
中的变量根据主题拆分为 light
与 dark
,并整理到 normalized.css
(Source Code)。并将这份 CSS 档放在 <head>
内,就可以让网页加载时引入,而主题的切换则透过 data-theme
属性来控制使用哪一组主题色。
Style Dictionary 的实际输出结构:
/* 建议的结构 - 优先使用系统偏好设定 *//* 深色主题(默认) */:root {--your-design-system-sys-color-primary: #D0BCFF;--your-design-system-sys-color-background: #141218;--your-design-system-sys-color-on-background: #E6E0E9;/* ... 其他深色主题 tokens */}/* 浅色主题 */html[data-theme='light'], .your-design-system-light {--your-design-system-sys-color-primary: #6750A4;--your-design-system-sys-color-background: #FEF7FF;--your-design-system-sys-color-on-background: #1D1B20;/* ... 其他浅色主题 tokens */}
以下我们将会介绍如何实作让使用者可以切换深浅色模式的功能,也就是本篇要介绍的 useTheme
Hook。
useTheme
描述
useTheme
的核心功能是控制 data-theme
属性的值,同时提供主题状态管理和持久化存储功能。
API
理想上我们希望当使用 useTheme
时,可以让我们更新 data-theme
以及取得当前的 theme
状态。
import { useTheme } from '@tocino-ui/core/hooks'export default () => {const { theme, resolvedTheme, toggleTheme, setTheme } = useTheme()return (<div><span>Current Theme: {theme}</span><span>Resolved Theme: {resolvedTheme}</span><button onClick={toggleTheme}>Toggle Theme</button><button onClick={() => setTheme('system')}>Use System Theme</button></div>)}
参数
返回 API
实作
可以看到上面引入了我们先前做的 Button 组件,并且透过 useTheme
去控制 data-theme
的值,这样就可以让设计系统能够支援切换深浅色主题。