Files
halo-dark-mode-plugin/docs/暗色模式残留排查报告.md
T

8.4 KiB
Raw Blame History

Halo 暗色模式残留排查报告

排查时间:2026-08-07 排查环境:腾讯云生产站 blog.liuhangyv.topHalo Pro 2.24.2 排查方式:Playwright 自动化全路由扫描,共 92 个后台路由

一、结论摘要

  1. 部署版本没有问题。服务端实际加载的 bundle.css 与本仓库 ui/build/dist/style.css 的 194 条暗色规则完全一致,不存在"部署了旧包"的情况。
  2. 73 个后台路由存在深浅色残留,19 个路由完全干净(主要是 Shop 插件全家桶、快照页、权限页)。
  3. 残留可归纳为 3 类根因
    • 插件 CSS 加载顺序在最前,同特异性规则被后加载的 Halo 核心样式覆盖;
    • UnoCSS 哈希类前缀已从 i-* 变为 uno-*,现有兜底规则匹配不到;
    • 第三方插件页面(AstraHub、RSS 订阅、私密文章、AI 评论等)基本没有覆盖。

二、扫描方法与产物

方法

  1. Playwright 启动持久化 Edge 上下文,复用已登录会话;
  2. 从 Vue Router 读取全部注册路由(92 个),逐页加载;
  3. 每页强制 data-halo-theme="dark",等待网络空闲后扫描;
  4. 扫描规则:可见且尺寸大于 50×20 的元素,背景 RGB 均 >235 记为浅色背景残留,直接文本颜色 RGB 均 <70 记为深色文字残留;
  5. 每页截图存档,结果按页面 + 元素分组去重。

产物(均在 workplace/

文件 说明
scan_dark.py 全路由扫描脚本
scan-results.json 原始扫描结果(92 页 × 元素级)
aggregate.txt 按元素/类名/问题聚合后的明细
shots/*.png 92 页深色模式截图
deployed-bundle.css 服务端实际部署的 CSS 快照
probe_conflict.py / fetch_bundle.py 样式表加载顺序与版本对比脚本

三、总体数据

指标 数值
扫描路由数 92
存在残留的路由 73
完全干净的路由 19
去重后的残留组 134
页面 × 元素残留条目 256
影响页面最多的残留 侧边栏 .menu-item-title.active 高亮背景(68 页)
次多 .empty-title 深色文字(16 页)

无残留的 19 个路由:/console/403、Shop 插件全部 11 个页面、/console/app-store/privacy-policy/console/posts/snapshots/console/single-pages/snapshots/console/users/auth-providers/console/users/roles

四、根因分析

根因 1(P0):插件 CSS 加载顺序在最前,同特异性规则被 Halo 核心样式覆盖

证据(来自 probe_conflict.py):

  • 插件 bundle.cssdocument.styleSheets 的第 0 张表;
  • Halo 核心样式 process-bar-DsZ2lvXx.css 是第 9 张表,加载更晚;
  • 双方存在同特异性规则,CSS 级联规则让"后加载者"胜出:
规则 特异性 结果
Halo.description-item-wrapper .description-item__label { color: rgb(17 24 39) } (0,2,0) 胜出
插件:[data-halo-theme="dark"] .description-item__label { color: var(--halo-text-secondary) } (0,2,0) 被覆盖

受影响页面/console/overview/console/schedule-calendar/console/theme 的详情描述项(名称、Halo、站点地址等文字仍是深色)。

修复建议

  • 对这类核心语义类统一加 !important
  • 或把前缀从 [data-halo-theme="dark"] 提升为 html[data-halo-theme="dark"],把特异性从 (0,2,0) 提高到 (0,2,1)。

推荐两者并用(提高特异性 + !important 双保险),因为 Halo 核心样式后续仍可能继续调整。

根因 2(P0):UnoCSS 哈希类前缀已变化,现有兜底规则失效

证据

  • 大量残留元素的类名是 uno-* 前缀(如 uno-ga61asuno-529526uno-b60d0h);
  • plugin-pages.css 中的兜底规则只覆盖 [class*="i-"],这是旧版 UnoCSS 的哈希前缀;
  • 部署 CSS 探针确认:menu-item-titleempty-titlealert-wrapper 三个关键字在暗色规则中完全不存在。

受影响页面AI Foundation 全家桶(每页 3–24 处)、数据迁移、装备/关注/照片/时间线/投票的卡片头部"新增"栏、SummaraidGPT 等。

修复建议

  • 新增 [class*="uno-"] 的兜底覆盖(背景、文字、边框三件套),并加 !important
  • 保留 i-* 规则,因为扫描中仍有少量 i-* 哈希(如 .i-p4hnaq)在真实页面出现,两个前缀并存。

根因 3P0):核心语义类缺覆盖

以下类在部署 CSS 中完全没有暗色规则,属于新增覆盖而非覆盖失效:

类名 残留内容 影响页面
.menu-item-title.active 高亮背景 rgb(243,244,246) 68 页
.empty-title 文字 rgb(17,24,39) 16 页
.alert-wrapper / .alert-default 背景 rgb(249,250,251) 3 页(概览、许可证、导入)
.description-item__label/content 文字 rgb(17,24,39) 3 页(同特异性失效,见根因 1

修复建议

  • 侧边栏高亮:覆盖 .menu-item-title.active(含 :hover),用 --halo-menu-item-active 变量;
  • 空状态:覆盖 .empty-title,用 --halo-text-secondary
  • 提示条:覆盖 .alert-wrapper 及各变体的背景/边框/文字。

根因 4(P1):第三方插件页面几乎未覆盖

插件/页面 残留类名 说明
AstraHub + 心愿便签 .ah-card.ah-topbar.ah-float-nav.ah-topbar-brand 两插件共用同一套 ah-* UI,覆盖一次可同时生效
RSS 订阅 .subscription-panel.feed-toolbar.feed-status-tabs.feed-stream.feed-brief__title 整个页面几乎整片浅色
私密文章 .focus-card.overview-card.list-card.empty-state 半透明白背景叠在深色上,文字也是深色
AI 评论自动处理 .setting-panel.form-row.sidebar-card.tabs-wrap.list-col.reply-card 设置页和日志页整片浅色
数据工坊 .modal-content.uno-* 卡片 弹窗与主内容区均残留
代码注入器 .uno-* 侧栏/编辑区 整页浅色
Meilisearch 概览 .uno-* 卡片与标题残留
日志查看器 .monaco-editor.margin.lines-content Monaco Editor 自带独立主题系统,仅靠 CSS 覆盖很难稳定
导入/存储工具 .uno-* 提示卡片、分页栏残留

修复建议

  • ah-*feed-*focus-card/overview-card/list-cardsetting-panel/form-row/sidebar-card 等语义类按插件页面补 !important 规则;
  • Monaco 不要硬啃 CSS,优先在 JS 里监听主题切换并调用 monaco.editor.setTheme('vs-dark'),或加载官方 dark 主题 CSS
  • 每个插件补完后再跑一次 scan_dark.py 验证零残留。

根因 5(P2):历史遗留规则与自相矛盾的选择器

  • components.css 中大量 .v-*Vuetify 类)在 Halo 2.25 的真实 DOM 中不存在,属无效规则(CLAUDE.md 已记录);
  • [class*="tag-"][class*="modal"] 等宽泛匹配容易误伤,建议逐步收紧;
  • utilities.csshalo-core.css 对链接色的规则互相覆盖,最终生效结果不明确;
  • halo-core.csshtml, body 编译后为 [data-halo-theme="dark"] html,该选择器永远不匹配(html 元素不会是其自身的后代),根背景兜底实际只靠 body 一条,页面在特殊滚动场景下仍有露白风险。

五、修复优先级清单

P0(一次重构后全站收益最大)

  1. 全局暗色规则前缀从 [data-halo-theme="dark"] 升级为 html[data-halo-theme="dark"]
  2. 核心语义类(.page-header.card-wrapper.description-item-*.table 等)加 !important
  3. 新增 .menu-item-title.active.empty-title.alert-wrapper 覆盖;
  4. 新增 [class*="uno-"] 兜底三件套;
  5. 修正根背景规则,让 html 本身也参与暗色。

P1(按插件逐个补齐并复扫)

  1. ah-*feed-*、私密文章、AI 评论插件语义类覆盖;
  2. Monaco 主题切换接入;
  3. 数据工坊、代码注入器、Meilisearch、导入/存储工具等 uno-* 页面复查。

P2(清理)

  1. 删除失效的 Vuetify 类规则,收敛宽泛匹配;
  2. 统一链接色规则,消除重复/冲突。

六、完整残留明细

workplace/aggregate.txt(134 组,含影响页面列表),原始数据见 workplace/scan-results.json