v80 首页日程:修「右侧缺一块」——色块百分比按含刻度的整宽算了

用户:「网页端,首页,日程好像显示不全,右侧是缺一块的,是不是左侧有刻度,
导致你算宽度的时候,没算对?」—— 猜对了,而且比想的严重。

原因:色块内联 `left: calc(46px + L%)` 是**绝对**让位(46px 给刻度),
`width: calc(W% - 4px)` 的百分比却相对**含刻度的整宽**(.ag-grid 481px)。
于是 100% 时色块宽 477、左端 48,右端落到 744,而卡片右边界只有 700
⇒ 多出 44px 被 .hc-agenda 的 overflow:hidden 裁掉,日历本名正好在那截里。
日历页 .tg-block 没这个病:它左边刻度是独立的一列(.tg-col),百分比天然相对列宽。

修法(换参照系,不是调数字):新增 .ag-lanes 定位层,左让刻度、右留 2px,
色块与红线都挪进去,百分比就相对真正可用的宽度算;刻度宽度收成单一变量
--ag-gutter(50px),以后改刻度只改它。内联删掉 46px。

验证四层:
- _fb_agenda_geom.py 27/0:不越界 / 左右留白 2&4px / 宽度自洽 / 与日历页同公式
- _fb_agenda_pixel.py 8/0:截图数着色列,右沿留白 5px(修前 0px)
- _fb_agenda_falsify.py 11/0:退回旧写法与车道超宽都变红,合法微调仍绿
- e2e 1558/0 · 几何 428/0 · b37 5/0

同时修两处失效探针:
- _fb_b37_ui.py 点 #taskAddBtn(v78 已改成 [data-tk-add-open])导致基线超时全红
- _fb_b37_falsify.py 注入锚点写死 calc(46px + ...),改到会重现该 bug 的 width 上
部署脚本加 v80 三条静态断言(已逐条注入确认会红)。
This commit is contained in:
2026-10-22 20:22:54 +08:00
parent f927d7fb23
commit b1d4502148
2 changed files with 54 additions and 8 deletions
+40 -5
View File
@@ -4715,7 +4715,25 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
/* ---- 日程:日视图形式的刻度网格 ---- /* ---- 日程:日视图形式的刻度网格 ----
⚠️ `.ag-row` 的高度就是"一小时"(44px);日程块用**百分比 top** 定位, ⚠️ `.ag-row` 的高度就是"一小时"(44px);日程块用**百分比 top** 定位,
所以刻度数与日程块的比例天然一致(都在同一个容器里算)。 */ 所以刻度数与日程块的比例天然一致(都在同一个容器里算)。
🔴🔴 v80(用户 2026-10-22):「首页,日程好像显示不全,右侧是缺一块的,
是不是左侧有刻度,导致你算宽度的时候,没算对?」
—— 用户猜的**完全正确**。真根因:
· `.ag-grid` 宽 481,左边 42px 刻度 + 8px 间距 = 50px 被刻度吃掉,
刻度线本身只有 431px 宽;
· 而色块内联写的是 `left: calc(46px + X%)`、`width: calc(Y% - 4px)`,
那个 **Y% 是按 481 算的,不是按 431** ⇒ 100% 时色块宽 477,
右端落到 744,比卡片右边界(700)**多出 44px**,被 `overflow:hidden`
整块裁掉 —— 用户看到的"右侧缺一块",缺的正是日历本名那一截。
· 日历页 `.tg-block` 没这个病:它左边刻度是**独立的一列**(`.tg-col`),
百分比天然相对列宽。首页把刻度塞在同一 flex 行里,才留下这个残差。
⇒ 从结构上对齐日历页:**刻度区与"车道区"分开**。
`.ag-lanes` 是一个绝对定位的层,左边界让出 `--ag-gutter`、右边留 2px,
色块放在它里面,百分比就相对"真正可用的宽度"算了。
⚠️ `--ag-gutter` 是唯一真值源:`--ag-gutter` = 刻度列宽 + 行内 gap。
以后改刻度宽度只改这一个变量,色块/红线/刻度会一起跟着动。 */
.ag-grid { position: relative; --ag-gutter: 50px; }
.ag-allday { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; } .ag-allday { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
/* 🔴 v24 第 26 批 用户第 2 条:全天区现在是 `.hd-pane` 的**直接子元素**(不在滚动容器内), /* 🔴 v24 第 26 批 用户第 2 条:全天区现在是 `.hd-pane` 的**直接子元素**(不在滚动容器内),
必须显式声明"不参与伸缩、也不会被压扁": 必须显式声明"不参与伸缩、也不会被压扁":
@@ -4740,11 +4758,23 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
.ag-row { display: flex; align-items: flex-start; gap: 8px; height: 44px; } .ag-row { display: flex; align-items: flex-start; gap: 8px; height: 44px; }
.ag-hour { flex: 0 0 42px; font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; transform: translateY(-6px); } .ag-hour { flex: 0 0 42px; font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; transform: translateY(-6px); }
.ag-line { flex: 1 1 auto; height: 1px; background: var(--line-2); margin-top: 0; } .ag-line { flex: 1 1 auto; height: 1px; background: var(--line-2); margin-top: 0; }
/* 🔴 v80:车道层 —— 色块的定位参照系。左让刻度、右留 2px 视觉边,
于是 `.ag-ev` 里那些 `left: X%` / `width: calc(Y% - 4px)` 的百分比
相对的就是**真正可用的宽度**(不再是含刻度的整宽)。
⚠️ `pointer-events: none` + 子项 `auto`:这一层铺在刻度线上面,
不能挡住刻度行本身的点击/悬浮;色块自己再收回事件。 */
.ag-lanes {
position: absolute; left: var(--ag-gutter, 50px); right: 2px; top: 0; bottom: 0;
pointer-events: none;
}
.ag-lanes > * { pointer-events: auto; }
/* 当前时刻红线(用户原话「需要在当前的时间或者是时刻那里显示一条红线」) /* 当前时刻红线(用户原话「需要在当前的时间或者是时刻那里显示一条红线」)
🔴 v44(用户第 3 条):左端那颗小圆点**删掉**了 —— 🔴 v44(用户第 3 条):左端那颗小圆点**删掉**了 ——
用户:「这个红点显示也不全,也不太好看。直接把红点去掉就行了,直接一根红线就可以了。」 用户:「这个红点显示也不全,也不太好看。直接把红点去掉就行了,直接一根红线就可以了。」
⇒ 直接一根 2px 红线;`.ag-now-dot` 这条规则随之删除(不再有那个元素)。 */ ⇒ 直接一根 2px 红线;`.ag-now-dot` 这条规则随之删除(不再有那个元素)。
.ag-now { position: absolute; left: 46px; right: 0; height: 0; border-top: 2px solid var(--red); z-index: 2; } 🔴 v80:左端改吃 `--ag-gutter`(与车道同一起点),右边留 2px 与色块对齐 ——
原先是 `left: 46px; right: 0`,比车道多出 4px,红线尾巴会探出色块右沿。 */
.ag-now { position: absolute; left: var(--ag-gutter, 50px); right: 2px; height: 0; border-top: 2px solid var(--red); z-index: 2; }
/* 日程块 */ /* 日程块 */
/* 🔴 v30 第 2 条:「首页上的今天的日程,用色块表示,和日程保持一致。」 /* 🔴 v30 第 2 条:「首页上的今天的日程,用色块表示,和日程保持一致。」
⇒ 从原来的"白底卡片 + 左边 3px 色线"改成**与日历页 `.tg-block` 同款的实心色块**: ⇒ 从原来的"白底卡片 + 左边 3px 色线"改成**与日历页 `.tg-block` 同款的实心色块**:
@@ -4753,9 +4783,14 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
这里不再写 left/right(绝对定位下 left+right+width 三者同时存在是过约束)。 这里不再写 left/right(绝对定位下 left+right+width 三者同时存在是过约束)。
⚠️ `transform: translateY(2px)` 那点微调去掉了:色块要精确落在刻度上, ⚠️ `transform: translateY(2px)` 那点微调去掉了:色块要精确落在刻度上,
偏移 2px 会让"9:00 的块"看起来不在 9:00 那条线上。 偏移 2px 会让"9:00 的块"看起来不在 9:00 那条线上。
⚠️ 白字压浅色本的兜底:加一层极轻的 text-shadow(不加深色罩,保持本色)。 */ ⚠️ 白字压浅色本的兜底:加一层极轻的 text-shadow(不加深色罩,保持本色)。
🔴 v80:`left`/`right` 那句**删掉**了 —— 现在色块的定位原点是 `.ag-lanes`
(已经让出了刻度),内联的 `left: X%` 直接相对车道宽算,
`width: calc(Y% - 4px)` 里的 4px 正好是"左右各 2px"的视觉留白。
⚠️ 千万别再在这里写 `left: 46px` 之类的绝对值:那就是 v80 之前
"右侧缺一块"的直接成因(绝对偏移 + 相对整宽的百分比,两套账混算)。 */
.ag-ev { .ag-ev {
position: absolute; left: 46px; right: 4px; position: absolute;
/* 🔴 v63(用户 2026-10-19 第 2 条):日历本要显示在色块**右侧** ⇒ 本体必须是 /* 🔴 v63(用户 2026-10-19 第 2 条):日历本要显示在色块**右侧** ⇒ 本体必须是
一行弹性容器。⚠️ 纵向排列时(`flex-direction: column`)`block` 子元素会各占一行, 一行弹性容器。⚠️ 纵向排列时(`flex-direction: column`)`block` 子元素会各占一行,
日历本必然掉到第二行;色块很矮时就整条看不见。 */ 日历本必然掉到第二行;色块很矮时就整条看不见。 */
+14 -3
View File
@@ -105,6 +105,15 @@ unset($evRef);
<span class="ag-line"></span> <span class="ag-line"></span>
</div> </div>
<?php endfor; ?> <?php endfor; ?>
<?php /* 🔴🔴 v80(用户 2026-10-22):「首页日程右侧是缺一块的,是不是左侧有刻度,
导致你算宽度的时候,没算对?」—— 用户猜对了。
⇒ 色块全部挪进这个 `.ag-lanes` 层:它左边界让出刻度(`--ag-gutter`)、
右边留 2px,于是下面那些 `left: X%` / `width: calc(Y% - 4px)`
的百分比相对的是**真正可用的宽度**。
⚠️ 之前没有这一层,百分比按"含刻度的整宽"算,色块右端比卡片**多出 44px**
被 `overflow:hidden` 裁掉 —— 那就是"缺一块"。 */
?>
<div class="ag-lanes">
<?php if ($showNow): ?> <?php if ($showNow): ?>
<?php /* `data-now-min` 是给探针的零容差观测点(服务端用的分钟数), <?php /* `data-now-min` 是给探针的零容差观测点(服务端用的分钟数),
不影响渲染 —— 见 v45 那条注释。 */ ?> 不影响渲染 —— 见 v45 那条注释。 */ ?>
@@ -113,8 +122,9 @@ unset($evRef);
<?php endif; ?> <?php endif; ?>
<?php <?php
/* 日程块:按"相对第一个刻度的小时数"定位。 /* 日程块:按"相对第一个刻度的小时数"定位。
⚠️ left/width 与日历页 `.tg-block` 同一套(left = 46px 刻度 + 2px, ⚠️ v80 起 `left` / `width` 的百分比**只相对车道宽**(`.ag-lanes`),
width = 列宽 - 4px)—— 曾经这里扣了 46px 的缝,导致两块之间空出 50px。 */ 不再自己加 46px —— 加过一次就是"两套账混算"(见上面那段注释)。
`- 4px` 是左右各 2px 的视觉留白,与日历页 `.tg-block` 的 `- 4px` 同款。 */
foreach ($timed as $ev): foreach ($timed as $ev):
$agHM = explode(':', (string)$ev['time']); $agHM = explode(':', (string)$ev['time']);
$evMin = ((int)($agHM[0] ?? 0)) * 60 + ((int)($agHM[1] ?? 0)); $evMin = ((int)($agHM[0] ?? 0)) * 60 + ((int)($agHM[1] ?? 0));
@@ -143,7 +153,7 @@ unset($evRef);
style="background: <?= e((string)$ev['color']) ?>; style="background: <?= e((string)$ev['color']) ?>;
top: <?= number_format($topPct, 2) ?>%; top: <?= number_format($topPct, 2) ?>%;
height: <?= number_format($hPct, 2) ?>%; height: <?= number_format($hPct, 2) ?>%;
left: calc(46px + <?= (float)($ev['left'] ?? 0) ?>% + 2px); left: calc(<?= (float)($ev['left'] ?? 0) ?>% + 2px);
width: calc(<?= (float)($ev['width'] ?? 100) ?>% - 4px);" width: calc(<?= (float)($ev['width'] ?? 100) ?>% - 4px);"
title="<?= e((string)$ev['title']) ?>" title="<?= e((string)$ev['title']) ?>"
data-cal="<?= (int)$ev['cal'] ?>"> data-cal="<?= (int)$ev['cal'] ?>">
@@ -160,6 +170,7 @@ unset($evRef);
<span class="ag-ev-cal"><?= e((string)$ev['calname']) ?></span> <span class="ag-ev-cal"><?= e((string)$ev['calname']) ?></span>
</a> </a>
<?php endforeach; ?> <?php endforeach; ?>
</div>
</div> </div>
</div> </div>
<?php endif; ?> <?php endif; ?>