来源:notes/documents/网页版页边档实施记录.md

网页版页边档实施记录

Status: done(2026-09-23 落地)

上游依据:notes/documents/网页版页外空白与页边列:原型与方案.md(note_a4c5ef9e206c42e2,原型与定案)、 web/docs/adr/0009-shell-contract-modules-replace-index-and-page.md(页边与索引分档)、 web/docs/adr/0013-page-canvas-and-split-reading.md(页内构图第三档)。 代码提交 f722e04(feat: 页边档——把页外那圈空白做成结构)。

落地的三件事

场景 页内构图 门槛(页这一列的宽度)
读一页文档,页不够宽 「页边 72 + 正文 640」整块在页里居中 < 976px
一页长文档 居中 + 右侧 200 目录轨道,缝 32;节号悬挂在版心左边 ≥ 976px,且这篇 ≥2 个标题
读一页文档,页够宽 左侧 168 页边列(档号整块粘住 = 书眉)+ 正文 640 + 右侧 216 目录 ≥ 1120px
日程里点一条笔记 同一页分两栏,左栏收缩、右叶滑出 ≥ 1196px 才并排

度量一个都没动:正文仍 640、页边基准仍 72、索引基准仍 300。变的是页边可以变宽、画布可以横向分栏, 以及宽屏上索引从 300 长到 420(视口 ≥ 1604px)。

实测(本地预览,CSS 像素)

视口 索引 页这一列 画布 正文 档号块 目录轨道 画布两侧余量 标题截断
2560 420 2076 1120 640 168,粘住 216 478 + 478 19/124
1920 420 1436 1120 640 168,粘住 216 158 + 158 19/124
1604 420 1120 1120 640 168,粘住 216 0 + 0 19/124
1512 300 1148 1120 640 168,粘住 216 14 + 14 76/124
1440 300 1076 976 640 712,随正文滚走 200 50 + 50 76/124
1340 300 976 976 640 712,随正文滚走 200 0 + 0 76/124
1280 300 916 792 640 712,随正文滚走 不出 62 + 62 76/124
1024 300 660 660 508 660 不出 0 76/124
430 430 430 430 398 430 不出 0 0

改前的同一组数(原型那篇笔记里量的):1920 画布 1080、两侧各 238;2560 各 558;1440 页这一列 1076, 差 4px 够不到当时 1080 的轨道门槛,整条目录不出现;索引 300 下 123 篇里 76 篇标题被截断。

门槛是硬的,两侧都复过:页这一列 1120 → 正文 640、1119 → 退回轨道档仍是 640、976 → 640、 975 → 只居中仍是 640。档号块粘住也复过:页往下滚 1500px 之后它的 top 仍是 26。

现在 1920:左侧 168 的页边列里档号粘在页顶,每一节的号悬挂在版心左边,右侧 216 的目录

同一屏 · 夜纸

同一个 1920 · 改之前:画布两侧各 238px 无人使用,72 的页边只有最上面三行有内容(原型那篇的对照图)

视口 1512 索引仍是 300,但页这一列 1148 ≥ 1120,页边档照样生效

视口 1440:页这一列 1076 ≥ 976,目录整条出现(改前差 4px,没有)

视口 1340:页这一列正好 976,画布塞满页列,正文仍 640

视口 1280:装不下门槛,退回「只居中」,两侧各 62

视口 1604:索引刚长到 420,页这一列正好 1120,页边档还吃得到

窄屏 430:脊变底部条、索引变抽屉、正文 398(两边各 16),与改前一致

日程里点开一条笔记:叶自己是一个容器,页边档不会误判叶内部宽(1920)

标题不足两个的短文档(1920):只多一列页边,不出目录轨道

实现期改掉、补上的四处(原型里没有的)

一、叶必须自己是一个容器。 .leaf 只有 712px 宽,而它外面那一千多像素的页这一列会让容器查询 误判:页边档一生效,叶里的正文被挤到 232px(实测)。给叶自己写 container-type: inline-size; container-name: page 之后,叶内正文回到 640,页边列与节号都不出现—— 叶里没有那么多地方,这两个东西本来就不该进去。

二、max-width 量的是内容盒,写门槛时不能把留白算进去。 这套 CSS 没有全局 box-sizing(默认 content-box),所以画布的 padding-inline 是另加的。第一版把留白算进了 calc(),正文变成 632 (差 8px 的「悄悄被挤瘦」),改成 calc(--margin + --tier-gap + --measure [+ --tier-gap + --rail-wide]) 才对——门槛就是构图本身的宽度

三、正文的 overflow-wrapanywhere 改成 break-word anywhere 允许把表格列压到比一个词还窄: 改前同一张表里「Markdown」在格子里折成「Markd / own」,最大列宽被压到 245。改后不折词,最大列宽 307。

四、两处小节号必须同源,以及悬挂的号要被档号块盖住。 页边那条是 .body 上的 CSS counter, 目录那条是 lib/heading-numbers.tsnumberHeadings(),两处读同一批 h2/h3,另外补了 5 条测试。 h3 出现在任何 h2 之前时得到 0.1——刻意保留:真出现就是一个显眼的提醒,比两侧计数器悄悄分家好。 其次,悬挂的号在 168 的页边里距页边右缘只有 16px,滚到档号块下面会两行字叠在一起,所以档号块给了 background: var(--paper)

复查

按「有没有东西贴到边缘、有没有横向溢出、console 有没有报错」把四档宽度(2560 / 1920 / 1604 / 1512 / 1440 / 1366 / 1340 / 1280 / 1024 / 430)、暗色、日程叶、标题不足两个的短文档都扫了一遍: scrollWidth 与视口相等,零 console 报错

顺带修掉的两条既有毛病(都不是这一轮引入的):表格里的词被折开(见上);.stamp 滚走(见上)。

没修的:1024 与 430 的正文是 508 / 398 而不是 640——这两档装不下「页边 72 + 正文 640」, 与改前逐像素一致,属于既有降级,不在这一轮的范围里。

留下的边界

  • 901–975px 之间既不挂节号也不出目录:页边那条通道还在(72),但宽到放得下一个号之前不挂。
  • 节号只收 h2/h3,目录也不收 h4、不做折叠。
  • 三条标准 CSS 里 text-box: trim-both cap alphabetic 要 Chrome 133+,本机 Chromium 129 量不到, 是按规范写的,没有实测证据;text-wrap: prettytext-spacing-trim: trim-start 本机支持。
  • --margin / --rail-wide / --rail-tier / --tier-gap 这四个数字中的任何一个,都必须回来改 App.css 里那两个门槛;改 --index 的 420 要连带看 ADR-0009 里的 1604。
  • 这一轮没有把余量填满,也不该填满:2560 上画布两侧仍有各 478px。目标是让余量有结构 (页边列 + 目录 + 悬挂节号),再往下填就要动度量了。