用 CSS 变量搭一套多主题系统:语义命名与 data-theme 实践
昨天写了一个环形专注计时器,其中用 CSS 变量做主题切换的部分比较有代表性,这里把设计思路展开聊聊。
一、为什么用 CSS 变量而不是切换 class
传统做法是为每个主题写一套 class,比如 theme-dark、theme-light,然后在 JS 里替换类名。问题在于样式分散:圆环一个文件里定义颜色,按钮另一个地方又定义一遍,主题一多必然遗漏。CSS 变量把"颜色"变成运行时可替换的值,所有组件只引用变量,主题定义集中在一处。
二、设计要点
1. 变量命名按语义而非颜色:用 --accent、--bg、--muted,而不是 --red、--gray。语义命名让主题只需要重新赋值,不需要理解每个组件的结构。
2. 挂载在 data-theme 属性上:html[data-theme="light"] { --bg: #f5f7fa; },切换主题时 JS 只改一个属性,比操作 classList 更干净,也方便和 localStorage、系统偏好(prefers-color-scheme)联动。
3. 过渡动画:在需要变色的元素上加 transition: background .35s, color .35s,主题切换就不是生硬的跳变。注意不要把 transition 加在 * 上,会引起意外的性能问题。
三、两个小坑
- CSS 变量不能用在 SVG 的 stroke 属性过渡上?其实可以:stroke: var(--accent) 完全合法,而且 transition 对它同样生效,环形进度条变色就是这么做的。
- 变量默认值要给足:var(--muted, #8b97a8),在变量未定义时给出兜底,避免主题加载时序问题导致文字变成默认黑色。
四、小结
把颜色收敛成语义化变量,是主题系统里投入最小、收益最大的一步。配合 data-theme 切换,几十行代码就能让整个页面支持多主题。这个技巧在我的专注计时器项目里已经落地,欢迎参考。
- 点赞
- 收藏
- 关注作者
评论(0)