首页 / 站务日志

Blog · 2026-10-18

浅色主题不是把滤镜反过来

做完深色站,加个 light 类、把背景调白,看着就完事了?我们这么干了一次,然后量了一下:有四个强调色在浅底上根本读不清。

这套站一开始只有深色。深色好看、好写、也安全(背景一黑,什么颜色上去都「挺酷」)。后来要加浅色,第一版的做法很朴素:html 上挂一个 data-theme="light",把一组 CSS 变量换掉,完事。

看着确实变了。问题是变了不等于能读。

先量,再改

对比度有标准算法(WCAG 的相对亮度),不难写:把颜色转成线性 RGB,算相对亮度,再按 (L1 + 0.05) / (L2 + 0.05) 求比值。正文要 4.5:1,大字与图形元素要 3:1。我写了个二十来行的脚本,把主题里每一个「会被当文字用」的颜色和三个背景色两两算一遍——结果不好看:

深色主题 14 组               全部通过
浅色主题 --mint   #34d399 on #f7f9ff   1.36  ✗(要 3.0)
浅色主题 --rose   #fb7185 on #f7f9ff   1.69  ✗
浅色主题 --violet #a78bfa on #f7f9ff   1.65  ✗
浅色主题 --gold   #b45309 on #eef2fb   4.49  ✗(要 4.5,差 0.01)

根因很直白:这三个颜色当初是给深色底调的亮色,浅色底上它们就是「浅色字写白纸」。修法不是加阴影,是换颜色——#34d399 换成 #047857,#fb7185 换成 #be123c,#a78bfa 换成 #6d28d9,金色 #b45309 换成 #9d470a。改完复算:4.9 / 5.6 / 6.3 / 5.6,全部达标。深色主题一个像素都不用动。

比变量更容易漏的:另一套样式表

真正尴尬的发现是工具箱。/Timarsky/tools/ 和 160 个详情页,跑的是自己那份 tools.css,它压根没接过主题——主站有浅色,工具站没有。/Timarsky/ 主页面又有一套自己的灯开关,写的是 body.light。

结果是:同一个域名下,首页有主题、工具站的首页有另一个主题、工具站的详情页没有主题。点了半天天色不变。

这轮把三者统一:页面 <head> 里放一段**同步**执行的预判脚本(读 localStorage、没存过就看系统偏好、把 theme-light 挂到 html),样式里的选择器从 body.light 改成 html.theme-light,切换按钮写到 .header .nav 和详情页的 .tp-actions,localStorage 键跟主站共用同一个(xkmyth-theme)。这样在一处切过,另一处打开就是同一个天色。

顺带说说搜索

同一轮还修了搜索的三件事,都很「不好看但也不报错」:

验收用的是二十条真实查询(时间戳、github ignore、json 格、字体、密码、子网 …),每条都要命中目标,缺一条就回去补别名——而不是「大概能搜到」。

记下来的三条

  1. 主题切换是 **CSS + 预判脚本 + 共享存储键** 三件套,少一件就会出现「点了没变」或「闪一下白」。
  2. 量化优先:对比度能算就别靠眼睛,脚本二十行,跑一次省掉一整轮返工。
  3. 搜索的关键词是**数据**,不是代码逻辑。塞进数据里、幂等重建,比在打分函数里写一堆 if 好维护得多。

顺手提一句:这两件事都写进了 CI 之外的复查脚本(audit_contrast.py、test_search.py),下次改配色或加工具,跑一遍就知道有没有把可读性还回去。

这一条对应的实现与验收记在 文档,颜色与主题的取舍写在 品牌页,逐轮改动见 版本日志。