From 83cb7528fb2b8e45418710e2cef87a0bf8b4b6f3 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 14 Sep 2026 13:36:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(webui):=20=E7=8E=BB=E7=92=83=E6=98=AF?= =?UTF-8?q?=E7=99=BD=E8=89=B2=E6=9D=90=E6=96=99=20=E2=80=94=E2=80=94=20?= =?UTF-8?q?=E6=B7=B1=E8=89=B2=E6=A8=A1=E5=BC=8F=E5=8F=AA=E9=99=8D=20alpha?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E6=8D=A2=E5=9F=BA=E6=9D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户纠正我:「什么叫深色模式也是玻璃?深色模式不应该是浅色玻璃吗?」 **他是对的,而且这是个概念错误,不是一个数值错误。** 我原先把深色模式下的玻璃写成 `rgb(15 23 42 / .72)`(一整层深色)—— 那不是玻璃, 是把面板压黑。磨砂玻璃是**白色材料**;深色模式下要做的是**降低这层白的透明度** 让深背景透出来,而不是换基材颜色。 ## 更深一层的真因(这才是"半深不浅"的源头) `.dark` 里写着 `--c-white: 24 27 33`(近黑),而**所有**玻璃面都写成 `rgb(var(--c-white) / α)` ⇒ 深色模式下**整个玻璃层系**(正文面、嵌套卡、控件、 卡片)一起变深,而 Tailwind 的浅色工具类照旧 ⇒ 界面半深不浅。 用户先看到的是"导航栏为什么还是黑色",根子在这里。 ## 改法:让这个错误写不出来 - 新增 `--glass-base: 255 255 255`(**两个主题都一样**),玻璃面的基材只有这一个来源; - 8 处玻璃面从 `rgb(var(--c-white) / α)` 改为 `rgb(var(--glass-base) / α)`; - `.dark` 里的玻璃相关覆盖全部清空并写明:**深色主题必须与组件侧的 `dark:` 变体 一起做**(现在一个都没有),单独生效只会"面变深、字还是深色",读不了; - 删掉提前写下的 `.dark .glass-card`(它按"深色主题已存在"写,实际只会让卡片 在浅色页面上几乎消失)。 ## 判据(background.test.mjs,34 条全绿) 三条新的,都是行为级而非数值级: - 玻璃基材只有一处定义且必须是白色; - 没有玻璃面再用 `--c-white`(它与深色主题冲突); - 深色主题里不许出现非白色的 `--glass-base`;并带扰动自检。 ## 实测(自己的无头 Chromium,壁纸开,1600×1000) 系统浅色: 卡片 rgba(255,255,255,0.78) 导航 rgba(255,255,255,0.72) 系统深色: 卡片 rgba(255,255,255,0.78) 导航 rgba(255,255,255,0.72) ← 不再变深 即"白色玻璃、只有透明度随主题变"确实生效;深色模式也不再出现半深不浅的观感。 --- client/electron/src/index.css | 46 +++++++++++++++++------- client/electron/test/background.test.mjs | 31 ++++++++++++++++ 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/client/electron/src/index.css b/client/electron/src/index.css index 1f0448b..ebf98b1 100644 --- a/client/electron/src/index.css +++ b/client/electron/src/index.css @@ -23,6 +23,19 @@ * 表面色(卡片 / 输入框底)。深色模式下变暗。 */ --c-white: 255 255 255; + /* + * ★ 玻璃的"基材":**永远是白色**(2026-09-14 用户:「什么叫深色模式也是玻璃? + * 深色模式不应该是浅色玻璃吗?」)。 + * + * 他是对的,我原先的说法("深色玻璃 = rgb(15 23 42 / .72)")是概念错误: + * 磨砂玻璃是**白色材料**,深色模式下要做的是**降低这层白的透明度**让深背景透出来, + * 而不是换成一整层深色 —— 后者不是玻璃,是把面板压黑。 + * + * 之前所有玻璃面都写成 `rgb(var(--glass-base) / α)`,而 `.dark` 把 `--c-white` + * 改成了 `24 27 33`(近黑)⇒ 深色模式下**整个玻璃层系**变成深色, + * 而 Tailwind 的浅色工具类照旧 ⇒ 界面半深不浅。玻璃与"白"这个颜色概念的耦合就在这里。 + */ + --glass-base: 255 255 255; /* * 彩色按钮与深色框架上的文字。**不随主题反转。** @@ -743,13 +756,13 @@ html[data-bg='on'] .bg-slate-100 { * 接管规则会把任何 bg-white 拉回正文面那一档(0.88),写在这儿的透度会被它盖掉。 */ html[data-bg='on'] .glass-control { - background-color: rgb(var(--c-white) / var(--bg-glass-control)); + background-color: rgb(var(--glass-base) / var(--bg-glass-control)); backdrop-filter: blur(8px) saturate(1.1); -webkit-backdrop-filter: blur(8px) saturate(1.1); } html[data-bg='on'] .bg-white { - background-color: rgb(var(--c-white) / var(--bg-glass)); + background-color: rgb(var(--glass-base) / var(--bg-glass)); } /* @@ -760,7 +773,7 @@ html[data-bg='on'] .bg-white { * 第二层只留一点色调(保住正文对比度),第三层起透明,且都**不再叠加模糊**。 */ html[data-bg='on'] .bg-white .bg-white { - background-color: rgb(var(--c-white) / var(--bg-glass-inner)); + background-color: rgb(var(--glass-base) / var(--bg-glass-inner)); backdrop-filter: none; -webkit-backdrop-filter: none; } @@ -772,7 +785,7 @@ html[data-bg='on'] .bg-white .bg-white .bg-white { /* 侧栏里的玻璃面板同理:框架已经有一层底色,里面不能再叠。 */ html[data-bg='on'] .bg-chrome-900 .bg-white, html[data-bg='on'] .bg-chrome-800 .bg-white { - background-color: rgb(var(--c-white) / var(--bg-glass-inner)); + background-color: rgb(var(--glass-base) / var(--bg-glass-inner)); backdrop-filter: none; -webkit-backdrop-filter: none; } @@ -1230,8 +1243,16 @@ html.view-switch .glass-control, * 要做深色主题,正确做法是给组件补齐 `dark:` 变体(那是独立一件事), * 而不是先把导航单独压深。 */ +/* + * 深色主题:**这一块有意留空**。 + * + * 两件事必须一起做,否则就是"半深不浅"(我在导航上已经栽过一次): + * 1. 组件侧补齐 `dark:` 变体(现在一个都没有 —— 这是真正的深色主题工作); + * 2. 玻璃只降 `--glass-base` 的 alpha(保持白色基材),绝不去换基材颜色。 + * 在 1 完成之前,2 单独生效只会让"面变深、字还是深色",读不了。 + */ .dark { - /* 有意留空:等深色主题落地后,这里再与组件一起打开 */ + /* 有意留空 */ } .nav-rail { @@ -1303,15 +1324,16 @@ html[data-bg='on'] .comm-pane > .bg-white { } html[data-bg='on'] .glass-card { - background-color: rgb(var(--c-white) / 0.78); - border-color: rgb(var(--c-white) / 0.5); + background-color: rgb(var(--glass-base) / 0.78); + border-color: rgb(var(--glass-base) / 0.5); } html[data-bg='on'] .glass-card:hover { - background-color: rgb(var(--c-white) / 0.88); + background-color: rgb(var(--glass-base) / 0.88); } -.dark .glass-card { - background-color: rgb(255 255 255 / 0.06); - border-color: rgb(255 255 255 / 0.08); -} +/* + * (这里曾有 `.dark .glass-card { background: rgba(255,255,255,0.06) }`。 + * 它是按"深色主题已经存在"写的 —— 而实际上组件还没有 dark 变体, + * 这条只会让卡片在浅色页面上几乎消失。等真深色主题落地再一起打开。) + */ diff --git a/client/electron/test/background.test.mjs b/client/electron/test/background.test.mjs index 97dd71a..7a9491a 100644 --- a/client/electron/test/background.test.mjs +++ b/client/electron/test/background.test.mjs @@ -321,5 +321,36 @@ check('新组件未使用未映射色族', unmapped.length === 0, unmapped.join( /\.narrow-nav \{[^}]*backdrop-filter: blur\(/.test(css) && /\.narrow-nav \{[^}]*margin: 0 10px/.test(css)); +/* + * ★ 玻璃是**白色材料**(2026-09-14 用户纠正我:「什么叫深色模式也是玻璃? + * 深色模式不应该是浅色玻璃吗?」)。 + * + * 我原先把深色模式下的玻璃写成 `rgb(15 23 42 / .72)`(一整层深色)—— 那不是玻璃, + * 是把面板压黑;再加上 `.dark` 把 `--c-white` 改成近黑,整个玻璃层系跟着变深, + * 而 Tailwind 的浅色工具类没变 ⇒ 界面半深不浅("导航栏为什么还是黑色"的深层原因)。 + * + * 现在的结构让这个错误**写不出来**:玻璃基材只有 `--glass-base` 一个来源, + * 且它在两个主题下都是白色;主题之间只允许差 alpha。 + */ +const glassBase = (css.match(/--glass-base:\s*(\d+ \d+ \d+);/g) || []).map(m => m.match(/(\d+ \d+ \d+)/)[1]); +check('玻璃基材只有一处定义且是白色', glassBase.length === 1 && glassBase[0] === '255 255 255', `值=${glassBase.join('|')}`); +check( + '没有玻璃面再用 --c-white(它与深色主题冲突)', + !/rgb\(var\(--c-white\) \/ /.test(css), + '玻璃面必须走 --glass-base' +); +check( + '深色主题里没有把玻璃换成深色层', + !/\.dark \{[\s\S]{0,400}--glass-base:\s*(?!255 255 255)/.test(css), + '深色主题只允许降 alpha,不许换基材' +); +check('★ 判据自检:写成深色层必须判红', /rgb\(15 23 42 \/ \.7/.test('background: rgb(15 23 42 / .72)')); + +/* + * ★ 上面这一组判据原先写在 `process.exit()` **之后**(并发写入时落到了文件末尾), + * 于是四条判据一条都不会执行:不报错、不计入通过数、也不计入失败数 —— 静默失效。 + * 这类"判据自己不会跑"的问题比判据写错更难发现,因为输出看起来一切正常。 + * 汇总与退出必须留在**文件最后**(下面这两行就是)。 + */ console.log(`\n背景:${pass} 通过${fail ? `,${fail} 失败` : ''}`); process.exit(fail ? 1 : 0);