fix(webui): 深色模式「只有通信页正常」—— 根因不是 alpha,是底没暗下来
用户原话:「webui 只有通信页面的深色模式正常了,剩下的三个页面深色模式 可读性都极差」。99a2d7a 只修了 `.glass-card` 那块(通信页走的就是它), 其余三页的面板走 `html[data-bg='on'] .bg-white` → `--bg-glass`,没跟进。 我第一版把这三档 alpha 从 0.9/0.84/0.55 降到 0.08/0.05/0.04,**仍然不够**。 ## 正确判据:逐个叶子文本节点,采样它**真实渲染的底色** 之前的探测全在数 DOM 祖先链上的 backgroundColor,而 `.app-backdrop` 是 `position:fixed` 的**兄弟节点**(不是祖先)⇒ 永远采不到壁纸与遮罩, 只能退回"壁纸均值 213"→ 得出"底是亮的"但与屏幕不符。 改成截图后用 pngread.mjs 逐像素采样:对每个叶子文本节点取其 bbox 内 出现最多的颜色当作它的实际底色,再算 WCAG 对比度。得到决定性的数字: 通信 最差 1.87:1 / 日历 最差 **1.19:1** / 联系 1.64:1 / 我的 1.42:1 (日历页「廿五」fg=rgb(138,146,161) bg=rgb(134,132,132) —— 字和底几乎同色) ## 根因:`--bg-dim` 是**比例**,比例压不住一张**浅**壁纸 用户 jianf 的壁纸均值 RGB 213(浅照片)、dim=56 ⇒ 213×0.44 ≈ 94,仍是中灰。 近白正文对 94 只有约 3.6:1;次要文字 gray-400 对 94~134 只有 1.2–1.4:1。 **没有任何文字颜色能救** —— 这与 background.test 的契约「玻璃是白色材料」 是同一件事的两面:深色下敢用近白基材,前提就是「背后是深底」, 而这个前提此前没人保证。 ## 改动 1. 新增 `--bg-dim-min`(`:root` 0% / `.dark` 92%),遮罩取 `max(var(--bg-dim), var(--bg-dim-min))` —— **取 max 而非覆盖**, 用户调得比下限高时仍以用户的为准,不下调他的选择。 2. 玻璃 alpha 收到 0.04/0.03/0.02(第三层从 `transparent` 改为 `--bg-glass-nested3` 的小值:深色下"透明"= 浅壁纸直接透上来)。 3. `.dark` 的 `--glass-card-wall-a` 0.1 → 0.04 与其它档对齐。 4. 浅色分支完全不变(dimMin=0% ⇒ max() 等价于原值,实测 glass 仍是 0.88、 遮罩仍是 `rgba(255,255,255,0.56)`)。 ## 验收(1280×800 真渲染采样,逐个叶子文本节点) 修复前:通信 1.87 / 日历 1.19 / 联系 1.64 / 我的 1.42(<4.5 的节点 17/88/22/26) 修复后:通信 6.14 / 日历 4.90 / 联系 4.96 / 我的 5.38(<4.5 的节点 **0/0/0/0**) 代价(明写在案):深色下浅壁纸被压得很淡(92%)。这是可读性优先的取舍, 壁纸仍在(8% + 玻璃质感 + 模糊),只是不再是主体。 ## 判据(theme.test 30 → 38,已同步 run-all 的棘轮) 新增 4 条,针对"归因错"这件事本身: · 深色下有压暗下限且 ≥90%(浅色下不干预) · 下限真的作用在遮罩上(**不是只定义变量**) · 用最坏输入(纯白 255 壁纸)实算 gray-400 对合成底 ≥ 4.5:1 · 判据自检:拿掉下限必须判红 变异自检跑过:下限改回 56% ⇒ 2 条红;下限定义了但没用上 ⇒ 1 条红。 `--revert-mutation` 之外的基本面:theme 38/0、background 44/0、 cross-client-theme 15/0、appearance-defaults 4/0。套件 broken 由 4 降到 3 (build stamp 因重构建而转绿),red 23 不变,无新增失败。
This commit is contained in:
@ -239,9 +239,32 @@
|
||||
*/
|
||||
--bg-scrim: 255 255 255;
|
||||
--bg-dim: 12%;
|
||||
/*
|
||||
* ★★ 2026-09-17:深色下的**压暗下限**(浅色下是 0 = 不干预)。
|
||||
*
|
||||
* 为什么需要它:遮罩是"黑 56%"这种**比例**,而比例压不住一张**浅**壁纸。
|
||||
* 用户 jianf 的壁纸均值 RGB 213(浅照片)、dim=56 ⇒ 遮罩后底 ≈ 213×0.44 = 94,
|
||||
* 仍是中灰;再叠各层玻璃白之后 108–134。而深色正文是近白(243),次要文字
|
||||
* gray-400 是 rgb(138,146,161) ⇒ 实测**最差 1.19:1**(日历页":root"那些日期)。
|
||||
* 这不是"文字颜色没跟上"(`--c-gray-*` 一直是反的),而是**底根本没暗下来**。
|
||||
*
|
||||
* 契约(background.test:"玻璃是白色材料"):深色下玻璃之所以能维持近白基材,
|
||||
* 前提就是"背后是深底"。所以深色必须保证这个前提 —— 壁纸是浅的时候,
|
||||
* 用户的 56% 不够,得抬到下限。
|
||||
*
|
||||
* 代价(明写在案):深色下浅壁纸会被压得很淡(92% ⇒ 只剩 8% 亮度)。
|
||||
* 这是**可读性优先**的取舍:用户报的正是"深色模式可读性极差",
|
||||
* 而且壁纸仍在(8% + 玻璃质感 + 模糊),只是不再是主体。
|
||||
*/
|
||||
--bg-dim-min: 0%;
|
||||
--bg-blur: 4px;
|
||||
/* 玻璃面板的不透明度:背景越花,面板需要越实才读得动。 */
|
||||
--bg-glass: 0.88;
|
||||
/*
|
||||
* 第三层嵌套:浅色下**仍然是透明**(你当初要的效果 —— 不要再叠白、别把壁纸吃掉)。
|
||||
* 深色下它必须有个小值,见 .dark 里的同名令牌与那一段的注释。
|
||||
*/
|
||||
--bg-glass-nested3: 0;
|
||||
/*
|
||||
* 嵌套面板那一层的不透明度。
|
||||
*
|
||||
@ -377,10 +400,46 @@
|
||||
* 否则一张浅色照片会在深色界面里舗成一块亮斑,正文完全读不动。
|
||||
*/
|
||||
--bg-scrim: 0 0 0;
|
||||
/* 深色下面板要更实:背景亮部与深色卡片对比过强时,文字会显得发灰。 */
|
||||
--bg-glass: 0.9;
|
||||
--bg-glass-inner: 0.84;
|
||||
--bg-glass-control: 0.55;
|
||||
/*
|
||||
* ★★ 2026-09-17:这三个值原本是 0.9 / 0.84 / 0.55 —— 壁纸模式下的**白底白字**。
|
||||
*
|
||||
* 机制:每个玻璃面都是 `rgb(var(--glass-base) / α)`,而 `--glass-base` **恒为白**
|
||||
* (用户定的契约:「玻璃是白色材料」,见 background.test 那组判据)。
|
||||
* 所以 α 就是「这层白有多实」,而它必须**跟主题反着走**:
|
||||
* · 浅色主题:页面底是白的、文字是深的 ⇒ 白面板实一点无所谓(底本来白);
|
||||
* · 深色主题:页面底是深的、文字是近白的 ⇒ 白面板**必须很透**,
|
||||
* 否则就是「白色面板 + 近白文字」。
|
||||
*
|
||||
* 实测事故(用户 jianf 账号:`bg_kind=image`、dim=56、blur=3,
|
||||
* 壁纸均值 RGB 213,212,225 —— 一张**浅**照片):只把 alpha 调到 0.08/0.05/0.04
|
||||
* 之后仍然**不够** —— 内层透明那一档让浅壁纸直接透上来,
|
||||
* 1280×800 真实渲染采样(逐个叶子文本节点采样其实际底色)最差 **1.19:1**
|
||||
* (日历页的日期/农历字:「廿五」fg=rgb(138,146,161) bg=rgb(134,132,132))。
|
||||
* 用户原话:「webui 只有通信页面的深色模式正常了,剩下的三个页面深色模式可读性都极差」。
|
||||
*
|
||||
* ★ 真正的根因不是 alpha,而是**底没暗下来**:dim 是比例(暗 56%),
|
||||
* 而 56% 压不住一张 213 的浅壁纸(213×0.44 ≈ 94,仍是中灰)。
|
||||
* 近白正文对 94 只有约 3.6:1,次要文字 gray-400 对 94/134 只有 1.2–1.4:1
|
||||
* —— **没有任何文字颜色能救**。所以深色下加了 `--bg-dim-min`(见 :root)。
|
||||
* 加了下限之后复测:四页最差 通信 6.14 / 日历 4.90 / 联系 4.96 / 我的 5.38,全部 ≥ 4.5:1。
|
||||
*
|
||||
* 为什么旧判据没拦住:它们只判 `--c-*` 色板(那套确实是反的),
|
||||
* 而这三个是 **alpha 档**,不在色板里 —— 与 `.glass-card` 写死白色是同一类盲区。
|
||||
* 现在 alpha 档也由判据**按实际合成**验算(theme.test 的「合成对比度」一条)。
|
||||
*
|
||||
* 低到什么程度:让深底主导,但保留一点点白当「玻璃的质感」
|
||||
* (全透明就失去玻璃层了,而且会让壁纸完全穿透面板)。
|
||||
*/
|
||||
--bg-glass: 0.04;
|
||||
--bg-glass-inner: 0.03;
|
||||
--bg-glass-control: 0.04;
|
||||
/* 第三层嵌套:深色下不能是透明(浅壁纸会透上来),给一点白压住即可。 */
|
||||
--bg-glass-nested3: 0.02;
|
||||
/*
|
||||
* ★★ 2026-09-17:深色下压暗下限 92%(浅色下是 0)。见 `:root` 里同一令牌的注释。
|
||||
* 实测:56% 时三页最差 1.19:1,92% 后四页全部 ≥ 4.5:1(1280×800 真渲染采样)。
|
||||
*/
|
||||
--bg-dim-min: 92%;
|
||||
|
||||
/*
|
||||
* 深色下的层次靠「边框亮于底」而不是阴影。
|
||||
@ -704,7 +763,13 @@ html[data-bg='on'] .app-backdrop {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: rgb(var(--bg-scrim) / var(--bg-dim));
|
||||
/*
|
||||
* `max()` 而不是直接 `var(--bg-dim)`:深色主题下用户把压暗调到 56% 时,
|
||||
* 浅壁纸仍会透成中灰(实测最差 1.19:1)。下限制在深色里给 92%,
|
||||
* 浅色里给 0(不干预)。取 max 而非覆盖,是为了**不下调用户的选择**:
|
||||
* 用户调得比下限更高时以用户的为准。
|
||||
*/
|
||||
background-color: rgb(var(--bg-scrim) / max(var(--bg-dim), var(--bg-dim-min)));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -825,8 +890,26 @@ html[data-bg='on'] .bg-white .bg-white {
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* ★★ 2026-09-17:第三层原本是 `background-color: transparent` —— **深色下的白底白字**。
|
||||
*
|
||||
* 那条规则的初衷是对的(2026-09-13 用户报「壁纸底上叠了太多不透明层,导致壁纸效果
|
||||
* 很差,几乎看不出来」):三层 0.82 相乘 = 0.995,壁纸被吃光了。
|
||||
* 但它的**代价在深色主题下不同**:浅色下第三层透明没关系(底本来就是浅的、字是深的),
|
||||
* 而深色下"透明"意味着**浅色壁纸直接透上来**,而上层文字是近白的 ⇒ 白底白字。
|
||||
*
|
||||
* 实测事故(用户 jianf 账号:壁纸 `image`、dim=56、blur=3,均值 RGB 213,212,225
|
||||
* 是一张**浅**照片):日历 / 联系人 / 我的 三页最差 **1.06:1**,而通信页正常 ——
|
||||
* 差别恰好是三页的面板都是「面板 > 卡片 > 内部」三层嵌套,最内层正文面被这条规则
|
||||
* 设成了全透明。用户原话:「webui 只有通信页面的深色模式正常了,剩下的三个页面
|
||||
* 深色模式可读性都极差」。
|
||||
*
|
||||
* 修法:保留"不再层层叠白"的本意,但**透明换成"很淡的白"**(深色下 0.04,
|
||||
* 浅色下仍是你当初要的透明)—— 壁纸在深色下不至于被吃光(0.08→0.05→0.04 三层
|
||||
* 合成约 0.16,仍看得见图案),而最内层正文面又能压住浅壁纸。
|
||||
*/
|
||||
html[data-bg='on'] .bg-white .bg-white .bg-white {
|
||||
background-color: transparent;
|
||||
background-color: rgb(var(--glass-base) / var(--bg-glass-nested3));
|
||||
}
|
||||
|
||||
/* 侧栏里的玻璃面板同理:框架已经有一层底色,里面不能再叠。 */
|
||||
@ -1482,8 +1565,8 @@ html.view-switch .pane-rise {
|
||||
/* 卡片面:白基材只降 alpha(0.92 → 0.06),深底便透上来。 */
|
||||
--glass-card-a: 0.06;
|
||||
--glass-card-hover-a: 0.1;
|
||||
--glass-card-wall-a: 0.1;
|
||||
--glass-card-wall-hover-a: 0.14;
|
||||
--glass-card-wall-a: 0.04;
|
||||
--glass-card-wall-hover-a: 0.07;
|
||||
/* 深色下靠「边框亮于底」而不是阴影来分层。 */
|
||||
--hairline-fg: 255 255 255 / 0.09;
|
||||
--hairline-fg-strong: 255 255 255 / 0.16;
|
||||
|
||||
Reference in New Issue
Block a user