8.4 KiB
8.4 KiB
Halo 暗色模式残留排查报告
排查时间:2026-08-07 排查环境:腾讯云生产站
blog.liuhangyv.top(Halo Pro 2.24.2) 排查方式:Playwright 自动化全路由扫描,共 92 个后台路由
一、结论摘要
- 部署版本没有问题。服务端实际加载的
bundle.css与本仓库ui/build/dist/style.css的 194 条暗色规则完全一致,不存在"部署了旧包"的情况。 - 73 个后台路由存在深浅色残留,19 个路由完全干净(主要是 Shop 插件全家桶、快照页、权限页)。
- 残留可归纳为 3 类根因:
- 插件 CSS 加载顺序在最前,同特异性规则被后加载的 Halo 核心样式覆盖;
- UnoCSS 哈希类前缀已从
i-*变为uno-*,现有兜底规则匹配不到; - 第三方插件页面(AstraHub、RSS 订阅、私密文章、AI 评论等)基本没有覆盖。
二、扫描方法与产物
方法
- Playwright 启动持久化 Edge 上下文,复用已登录会话;
- 从 Vue Router 读取全部注册路由(92 个),逐页加载;
- 每页强制
data-halo-theme="dark",等待网络空闲后扫描; - 扫描规则:可见且尺寸大于 50×20 的元素,背景 RGB 均 >235 记为浅色背景残留,直接文本颜色 RGB 均 <70 记为深色文字残留;
- 每页截图存档,结果按页面 + 元素分组去重。
产物(均在 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.css是document.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-ga61as、uno-529526、uno-b60d0h); plugin-pages.css中的兜底规则只覆盖[class*="i-"],这是旧版 UnoCSS 的哈希前缀;- 部署 CSS 探针确认:
menu-item-title、empty-title、alert-wrapper三个关键字在暗色规则中完全不存在。
受影响页面:AI Foundation 全家桶(每页 3–24 处)、数据迁移、装备/关注/照片/时间线/投票的卡片头部"新增"栏、SummaraidGPT 等。
修复建议:
- 新增
[class*="uno-"]的兜底覆盖(背景、文字、边框三件套),并加!important; - 保留
i-*规则,因为扫描中仍有少量i-*哈希(如.i-p4hnaq)在真实页面出现,两个前缀并存。
根因 3(P0):核心语义类缺覆盖
以下类在部署 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-card、setting-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.css与halo-core.css对链接色的规则互相覆盖,最终生效结果不明确;halo-core.css的html, body编译后为[data-halo-theme="dark"] html,该选择器永远不匹配(html 元素不会是其自身的后代),根背景兜底实际只靠body一条,页面在特殊滚动场景下仍有露白风险。
五、修复优先级清单
P0(一次重构后全站收益最大)
- 全局暗色规则前缀从
[data-halo-theme="dark"]升级为html[data-halo-theme="dark"]; - 核心语义类(
.page-header、.card-wrapper、.description-item-*、.table等)加!important; - 新增
.menu-item-title.active、.empty-title、.alert-wrapper覆盖; - 新增
[class*="uno-"]兜底三件套; - 修正根背景规则,让
html本身也参与暗色。
P1(按插件逐个补齐并复扫)
ah-*、feed-*、私密文章、AI 评论插件语义类覆盖;- Monaco 主题切换接入;
- 数据工坊、代码注入器、Meilisearch、导入/存储工具等
uno-*页面复查。
P2(清理)
- 删除失效的 Vuetify 类规则,收敛宽泛匹配;
- 统一链接色规则,消除重复/冲突。
六、完整残留明细
见 workplace/aggregate.txt(134 组,含影响页面列表),原始数据见 workplace/scan-results.json。