页面外观

每页 HTML = 内容 HTML + 模板函数拼装的页面外观。模板为纯 TypeScript 函数(renderLayout(data: TemplateData): string),零模板引擎依赖,类型安全,用户可控字符串统一转义。

布局结构

页面自上而下分三层:

  • Header(通栏):站点品牌、搜索触发器、语言切换、主题切换;sticky 悬浮于整窗滚动内容之上,恒为悬浮盒(毛玻璃底 + 细边框);圆角随滚动量连续插值,页面顶部时为卡片级 14px,随向下滚动在前 120px 内按 easeOutCubic 扩张为胶囊(半高 28px)
  • 子文档 Tab 栏(通栏):docdoc.json 声明多个子文档时渲染;普通流透明一行,不常驻,滚动时随内容向上滚出视口、钻入 Header 外层的不透明画布之下
  • 主体(左右两栏):侧栏与文档区。侧栏趴在暖色画布上(宽度由 --sidebar-width 变量驱动,可拖拽调宽并记忆);文档区是一张浮于画布上的白色卡片(圆角、细边框、微阴影,高度跟随内容),卡片内是文档正文、Minimap 与上一页/下一页导航;站点页脚(版权、构建时间)独立浮于卡片下方的画布上,视觉与正文脱离

整窗滚动模型:Header position: sticky 悬浮(外层铺不透明画布,遮蔽滚动经过的 Tab 栏与正文);Tab 栏不悬浮,随内容向上滚走;侧栏 sticky——滚动时与正文一起向上,触碰 Header 下沿(--header-height,72px)后固定,正文继续向上。视口高度一律采用 svh 动态视口单位(带 vh / -webkit-fill-available 回退),规避移动端浏览器大视口(lvh)大于可视区造成的底部多余滚动空间。html 的 scroll-padding-top 按 Header(--header-height)+ 16px 统一为锚点跳转与程序化滚动让位。

图标体系

界面图标全部使用 Phosphor Icons(MIT License)bold 字重,构建期内联为 SVG(currentColor 继承文字颜色),零运行时依赖、无字体文件。图标清单由 scripts/gen-icons.mjs 从 @phosphor-icons/core 生成到 src/chrome/icons.ts。

标题图标复用同一图标清单:任意级别的标题中可书写 <Icon name="rocket-launch" />,无论书写位置,图标永远呈现在标题最前;构建期标题净化把它从侧边栏条目、搜索索引与标题锚点中剥离,rehypeHeadingIcons 在 slug 计算前移除图标节点保证锚点干净。

组件与拼装时机

组件 拼装时机 内容
Header 构建期 站点图标与名称、搜索触发器(⌘ K pill)、语言切换器(多语言时)、主题三态切换(太阳 / 月亮 / 显示器图标按钮)
子文档 Tab 栏 构建期 docdoc.json 声明的子文档列表,多于一个时渲染为 Header 与主体之间的通栏一行,当前子文档高亮
Sidebar 构建期烘焙 三种渲染器逐页生效(doc.docdoc.json 的 renderer 定文档级缺省,各目录 metadata.docdoc.json 的 renderer 可覆盖、最深一级目录生效,同一文档内可混合出现):tree 可展开折叠树(折叠箭头 + 目录行 + 条目,当前页高亮、祖先目录展开);submenu 逐级进入(面包屑链 + 当前目录条目,点击目录行进入;目录首页以同标题条目呈现在条目列表首位;面包屑仅剩文档标题时(文档根页)不渲染该行,避免与子文档 Tab 重复);group 分组恒展(目录题作小号纯文本分组标签,目录首页以同标题条目呈现在组内首位,全部条目始终展开、无折叠,嵌套目录作缩进子分组)。选中态三形态统一为白卡片:tree 的目录行或页面行、submenu 与 group 的页面条目(含重复呈现的目录首页条目)。均支持拖拽调宽
Minimap 构建期烘焙 当前页标题大纲(带列表图标),滚动联动高亮
上一页/下一页 构建期烘焙 按目录序渲染相邻两页链接(左右箭头图标)
Try it 面板 构建期烘焙容器,客户端水合 接口文档专用,数据与语义见站内搜索 ?接口标记
Footer 构建期 独立于内容卡片、浮于画布上的站点页脚:版权信息(docdoc.json 顶层 copyright,缺省为 © 年份 + 站点名)、构建时间(构建机本地时区格式)

构建期烘焙保证页面无闪烁、无客户端渲染依赖;模板函数的输入契约见站内搜索 ?TemplateData。

亮暗主题

首帧前内联脚本按 localStorage 记忆的选择或系统偏好设置 data-theme,避免错误主题闪现;CSS 变量驱动两套配色,代码块在两种主题下均保持深色外观。构建期不烘焙主题选择,切换即时生效。

rootPrefix 机制

每页按自身深度计算指回站点根的前缀(../..、./ 或 /my-docs/),所有资源引用、页间链接与内容接口请求都拼接该前缀。同一份产物因此无须改动即可在三种环境下正确工作:

环境 站点根
域名路由 /
路径前缀路由 /:name/
preview 命令行指定的根

客户端脚本

assets/docdoc.js 为单文件 IIFE,零运行时依赖,只做交互增强:

行为 说明
搜索弹窗 ⌘ K / Ctrl-K 唤起,防抖调用站点的全文搜索接口渲染命中列表,键盘上下选择、回车跳转
主题切换 Light / Dark / System 三态,localStorage 记忆,跟随系统偏好变化
Sidebar 折叠 目录节点的展开与收起、当前页高亮、拖拽调宽并记忆
Header 滚动态 窗口滚动时切换 page-scrolled 类(阴影),并按滚动量逐帧插值 Header 悬浮盒圆角
Minimap 联动 滚动时同步高亮标题大纲
代码块复制 代码块右上角复制按钮,成功后短暂勾选反馈
Try it 面板水合 读取烘焙的 data-docdoc-try 数据构建表单;HTTP 面板实发请求,NATS 面板构建并复制请求载荷

纯静态打开(无服务端)时优雅降级:导航照常可用,搜索提示服务不可用。