跳转到主要内容

为大表格腾出阅读空间

文档框架与表格组件证据、阅读概念测量,以及 OINK 技术表格的有限候选方向。
历史研究;当前行为见 1.4.0 决策

研究日期:2026-10-26。本研究为 OINK 1.4.0 的表格阅读设计提供了依据。接受的决策 与 表格指南 描述已发布行为,并替代下文的入口与范围建议。

通过显式“阅读表格”操作打开大型原生对话框,是最值得继续评估的候选方案。 它给桌面表格增加空间,同时保留文字大小、原表语义和简短的返回路径。许多表格只需在正文内拓宽;实测扩展包样本在桌面端采用这种模式就已能容纳全部列。在 390px 视口下,对话框仅增加 16px 宽度,窄屏下仍保持横向滚动。五个文档框架默认均采用原生表格配横向滚动容器,而第三方表格库在提供数据操作的同时也增加了集成与维护负担。

分清布局、内容与发布状态的证据

当时的公开标签快照为 v1.3.2,标签引用为 68cfbbdc177064e2c28277c09c385d78e5363ffd。研究开始时,主题 HEAD 为 7bc8658bc1be13ef0ad3050b9d9f6862f8f1f65f,站点 HEAD 为 99751179eefada3fa7a91318c792ddac46d7e6bf,两个工作树均有未提交修改。本实验中验证的短标记 .wide 随后纳入 OINK 1.4.0,详见 组件契约。

本地检查的模块包括 oink/layouts/_partials/content/table-render.html、table-body.html、assets/scss/td/_content.scss、_table.scss、预设与字体令牌,以及界面协调器。.wide/.td-table--wide 控制内在尺寸和标识符换行;.full-width 使用文章可用画布。.matrix 提供首列行表头、受限高度的双轴滚动,以及现有粘性表头/首列 CSS。该 CSS 给每个表头设置 top:0,未计算多行累计偏移,也未设置移动端首列宽度上限。.fields 输出定义列表。普通题注位于表格内部,编号 Book 表格题注位于外层 figure(见 表格指南 和 输出契约)。

选取的下游站点源文件 有限样本与用途
pigsty.cc/content/docs/infra/param.md,NGINX 分组 4 列 × 14 行正文;带链接的参数标识符与描述
pgext/content/list/pkg.md,第 44–69 行 6 列 × 24 行正文;扩展包/版本/仓库/分类/RPM/DEB 比较
pigsty.cc/content/docs/ref/linux.md,概览 8 列 × 14 行正文;OS/架构及 PG18–PG14 支持状态
piglet.run/content/docs/reference/vscode/_index.md 2 列 × 7 行正文;小表格反例

下游站点快照分别为:pigsty.cc 的 efaf7b19b442ddb284106418c78854552d949e9e、pgext 的 ab87fc7e5707d57f55129d3c45874abcc16fdef8、piglet.run 的 5a1572e6f9110cd5e8ef6e75cd50d9c4b6429f98;均固定使用 OINK v1.3.2。另一张包含 616 行的扩展目录不在本次原型测试范围内。

这些样本区分了 多列、多行、长单元格 和 复杂表头。拓宽视口主要帮助第一类;粘性定位帮助第二类;换行帮助第三类。多行和合并表头需要显式关联与偏移计算。原型所选表格均只有单行表头且无合并单元格。GFM 管道表格语法本身定义单行表头和行内单元格内容(GFM 表格、WAI 多级表头)。

五个框架以溢出处理为共同基线

调研检查了五个文档框架的官方文档与默认主题源码。五个框架默认均不提供独立的全屏表格阅读器。 文档链接对应 2026-10-26 读取的页面;源码链接锁定具体提交。

框架快照 默认表格行为 可选或自定义边界
Material for MkDocs,0f044dbe,2026-10-24 Markdown tables;将原表包入局部横向滚动容器,并保留未包装回退 排序通过按需接入 Tablesort 5.3.0 实现;默认不提供阅读器、固定列或表格复制(见 指南 与 CSS)。
Docusaurus Classic 3.10.2,f37f9035,2026-07-10 MDX/GFM 渲染表格;Infima 0.2.0-alpha.45 使用 display:block; overflow:auto 通过 MDX/remark/rehype 提供自定义扩展(见 MDX 映射 与 Infima CSS)。
VitePress 1.6.4,1fc537b7,2025-08-05;2.0.0-alpha.21 快照 d6d7a970,2026-10-26 两个快照均使用块级表格和横向溢出 2.0 快照默认增加 tabindex="0";可通过 Vue 组件定制交互(见 1.6.4 CSS 与 2.0 焦点插件)。
Astro Starlight 0.42.7 快照 af9557ea,2026-10-24 Markdown 表格样式使用 display:block; overflow:auto .not-content 提供样式隔离;整页阅读与代码全屏由社区插件提供(见 CSS 与 插件目录)。
Nextra 4.6.5 快照 d6e80e1d,2026-06-23 官方 Table 组件包装带样式和横向溢出的 HTML 字面 MDX <table> 需显式使用 Table 或加入白名单(见 源码 与 HTML 边界)。

所检查代码的许可证均为 MIT:Material、Docusaurus、VitePress、Starlight 和 Nextra。Docusaurus 文档另用 CC BY 4.0。

对静态 Hugo 站点,直接适用的模式是语义 HTML、局部滚动、构建期焦点属性和可选渐进增强。Material 的 挂载代码 使用 RxJS;Classic 使用 React/MDX,VitePress 使用 Vue/Vite,Starlight 使用 Astro,Nextra 使用 Next/React。

丰富组件增加数据操作,也增加维护责任

当前版本差异明显。DataTables 3.1.4 已不再依赖 jQuery。TanStack Table 9.3.1 使用 constructTable、按需功能选择和 Store 响应式绑定(见 DataTables v3 依赖边界 和 TanStack v9 公告)。

组件 适用方向与可用操作 集成与维护边界
DataTables 3.1.4,2026-10-13 发布;MIT,核心无必选运行时依赖 通过内部数据模型增强 HTML 表格;核心提供排序/搜索/分页;Buttons、FixedColumns、FixedHeader、Scroller 可选 最接近系统化表格操作的候选方案。滚动可能复制或移动表头;支持复杂 thead,不支持 tbody 跨格(见 发布、发布包、跨格限制)。
Tabulator 6.7.1,2026-10-22 发布;MIT,无必选运行时依赖 网格渲染、排序/筛选、冻结列、列分组、剪贴板和虚拟渲染 HTML 导入器读取首个 tbody 的 td,会丢失 .matrix 的行表头 th 语义,且不保留通用 caption/scope/headers(见 发布、发布包、导入器)。
TanStack Table core 9.3.1,2026-10-12 发布;MIT,依赖 @tanstack/store ^0.11.2 无界面的排序/筛选/固定/选择/跨格逻辑;支持 vanilla 集成 维护者需自行实现 HTML 导入、渲染、控件、样式、焦点、导出和对话框;虚拟化器另行接入(见 元数据、固定版本包、vanilla 指南)。

DataTables 的 FixedHeader/FixedColumns 是可选扩展;Scroller 要求等高行,不适合自动换行的技术描述。Tabulator 输出面向单元格导航的 ARIA grid 结构。TanStack 跨格 API 需要显式定义列,不支持任意 HTML 合并格的无损导入。上述发布包均未内置全屏阅读对话框(Tabulator 的 printFullscreen 用于打印布局)(见 Scroller、Tabulator 导航、Print 源码、TanStack 跨格指南)。

复制默认行为也各不相同。Buttons 4.1.2 按当前排序/筛选规则导出显示数据并为跨格位置补空值,默认不开启公式转义。Tabulator 6.7.1 用 TAB 和换行拼接单元格值,不做通用引号包裹或公式转义。Tablesort 5.7.1 是轻量的无依赖 MIT 排序库,保留原表行并支持表头 Enter 键触发,不含阅读器、筛选或导出层(见 Buttons 源码、Tabulator Clipboard、Tablesort 源码)。

比较交付字节时同时说明排除项

测量使用 14 个固定版本 npm tarball,并核对 registry integrity。发布者提供的 minified 文件按原样测量。Gzip 使用 Python 3.14.8、zlib 1.2.12 和 gzip.compress(data, compresslevel=9, mtime=0);合计为各文件分别压缩后相加。

测量的交付内容 Minified 字节 Gzip-9 字节
DataTables 3.1.4 核心 JS + 默认 CSS 153,523 46,181
上述内容 + Buttons 4.1.2、FixedColumns 6.1.1、FixedHeader 5.1.2 JS/CSS 249,015 72,480
Scroller 3.1.1 JS/CSS,另加 13,300 4,389
Tabulator 6.7.1 完整 UMD JS + 默认 CSS 483,872 107,512
TanStack 9.3.1 所选阅读器逻辑,本地打包 49,505 14,248
TanStack 9.3.1 全部 core 导出及绑定/渲染辅助,本地打包 115,146 30,983
TanStack virtual-core 3.19.7,独立本地打包 32,872 9,745
Tablesort 5.7.1 核心 + 数值比较器 3,756 1,763

DataTables 核心 JS 为 123,516/42,338 字节,CSS 为 30,007/3,843 字节(minified/gzip)。扩展合计使用 Buttons、FixedColumns、FixedHeader、Scroller 及匹配的 -dt CSS。可选样式适配 JS 为四包合计另加 2,501/1,279 字节,Scroller 适配器另加 650/326,不含初始化、对话框、本地化、JSZip/pdfmake 和 source maps。Buttons 复制实现已在主文件中,不重复计入兼容 shim。Tabulator 完整包 包含全部内置模块;Tablesort 仅提供排序功能。

TanStack 测量来自本地 esbuild 打包:使用 Node 26.12.0/npm 11.20.0、esbuild 0.25.11,将 core 9.3.1 与 Store 0.11.2 以 --bundle --minify --format=esm --platform=browser --target=es2020 --legal-comments=inline 及生产 NODE_ENV 打包。所选入口导出 constructTable、tableFeatures、排序/筛选/固定/跨格功能、排序/筛选行模型、storeReactivityBindings 和 FlexRender。全部核心入口导出 core 命名空间及后两个辅助项;虚拟化入口单独导出 virtual-core。Metafile 确认无外部 import。14,248 字节 gzip 的逻辑样本仅包含无界面状态管理,不含 UI、CSS、HTML 导入器、无障碍控件、对话框、复制器或虚拟化器(见 core 包、Store、Virtual)。

概念验证中的桌面拓宽收益远大于手机

外部原型使用真实同级文档站 Hugo 构建,内容通过仓库外挂载。PGEXT 专用短代码转成显式标签/链接,参数片段链接解析到原始来源 URL,支持状态图标增加“Supported”文字等价项。新增题注和 .wide 作为实验适配,各阅读模式复用相同的生成表格数据。构建使用同级主题替换,关闭两个 workspace 机制,并将输出、缓存和资源目录放在仓库外。

比较外壳采用 230px 侧栏、桌面主区 40px 留白、68ch 正常正文宽度与 1130px 可用画布,表格与预设样式来自实际生成的 OINK CSS 与字体。另行生成的真实表格指南页面测得桌面表格视口为 770px、移动端为 358px。

扩展包表格滚动视口 正常正文宽度 正文内拓宽 原生对话框 独立页面模式
桌面 Paper/Terminal 652.80px 1130px 1358px 1408px
桌面 Slate/Ink 686.38px 1130px 1358px 1408px
移动端,全部四种预设 358px 358px 374px 374px

这些是本地 qa.json 在 1440×1000 和 390×844、DPR 1 下的测量;各预设深浅色几何尺寸一致。文字始终保持 16px,代码 14px。移动端表格内在宽度约为 969–1009px。桌面正文内拓宽已能容纳六列样本;对话框主要增加受限高度、常驻控件,以及与正文隔离的阅读视野。桌面对话框的表格可见高度为 847.20px,页面模式为 897.20px;移动端因控件换行,对话框高度为 711.02–741.20px。

正文内拓宽的上下文切换成本最低。对话框增加桌面空间,并保留直接返回文章的路径。独立页面在桌面上只多 50px,移动端宽度不变;其优势在于可重新加载与 URL 分享,但返回时不保留原文章滚动位置与焦点。三种模式均不缩放文字,也不调用 Fullscreen API。

通过 Playwright 1.62.1 驱动的 Chromium 151.0.7922.34 检查了 16 组预设 × 深浅色 × 设备组合,每组包含三个阅读概念与基线。扩展包样本通过原节点身份、ID 唯一性、题注/表头 scope、样式/字体加载、标题初始焦点、Enter 打开、Escape/关闭返回、正反 Tab 边界、工具栏稳定性、控件与表格区域分离、页面模式重载检查。未记录整页溢出;另检查了三个移动端样本和 320px Terminal/深色溢出探针。单独检查保留了链接目标与文字选择,并把正文内横向滚动恢复到 180px。截图审阅覆盖 48 张概念截图和总览图,且 Paper/浅色/桌面对话框的 axe 扫描报告零违规。

参数与版本样本的首列分别占 374px 移动端阅读视口的 59.3% 和 58.3%,说明移动端适合加入可选的首列宽度上限。各预设保持鲜明区分:Paper 的 Plex Sans 与克制边框、Slate 的 Inter 与圆角控件、Ink 的平面利落几何,以及 Terminal 的等宽控件和 Plex Sans 正文。

复现材料包括仓库外保存的构建器、源码清单/哈希、生成的参考输出、QA/检查 JSON 和截图集,使用 macOS ARM64 上的 Hugo 0.168.0+extended+withdeploy、Go 1.27.3,以及 Node 26.12.0、npm 11.20.0、Python 3.14.8。

本原型验证聚焦 Chromium 桌面与触屏模拟下的单行表头场景;Firefox/WebKit、屏幕阅读器测试、强制颜色、200/400% 缩放、合并表头、协调器集成及打开状态下打印归入正式实现验收。

小型阅读器更容易保全现有文档

建议首期采用显式 阅读表格 操作、原生对话框,以及原节点的一次移动/恢复生命周期。只靠悬停无法兼顾触屏和键盘发现;整表点击会与选择、链接、滚动冲突。可见标题/关闭控件、具名滚动区、标题初始焦点、受限 Tab 导航、Escape,以及带保护的焦点/滚动恢复,都是核心要求。复用 OINK 界面协调约定。接近全视口的对话框与浏览器全屏不同,后者的标准不允许把 <dialog> 作为请求目标(见 APG 对话框 与 Fullscreen Standard)。

保留 caption/th/scope/headers 和原 ID。移动原表可避免克隆冲突与状态分叉,但继承样式、外层编号题注、外部 ARIA 引用及脚注仍需显式处理。原生表格可以包含链接和排序按钮,无需转为 ARIA grid。先支持单行粘性表头,复杂表头在累计偏移验证前保持普通滚动。默认使用舒适间距,紧凑模式只改内边距、不改字号。可选首列固定需给移动端留出充足的阅读宽度(见 APG table、APG grid、表头语义)。

.wide/.td-table--wide 仍只控制布局,.full-width 仍受文章画布限制,.matrix 保留语义,.fields 不启用阅读器。无 JS 时内容保持可读;Print 展开静态表格,Markdown 保留源内容,RSS 保留静态/摘要边界且不混入阅读控件。

若后续增加 TSV 复制,建议按作者顺序复制 整张符合条件的表格(含视口外的行列):链接转为文本标签,代码保留文本,排除隐藏控件与装饰符号,有实际含义的图标提供文字等价项。首期拒绝隐藏数据行/列、嵌套表格、行长不等、多行表头,以及任何 DOM rowSpan/colSpan 不为 1 的情况(包括 rowspan="0"),使用 TAB 分隔列、LF 分隔行、规范化单元格内空白,并对跳过前导空白后以 = + - @ 开头的单元格前置单引号(见 HTML 表格模型、DOM 文本、Clipboard 2026-06-24 工作草案、OWASP 电子表格注入限制)。

聚焦原生表格的小型阅读器既保留未来引入数据网格的可能,也避免立即维护第二套数据模型。缩减后的实现边界见 接受的决策。

审阅后接受的方向

维护者审阅后选择显式组合 {.wide .expand} 与角落直接展开按钮(悬停或聚焦时显示,触屏常显),排除表格上方工具栏、省略号菜单和 TSV 复制。最终发布行为由 接受的决策 与 当前契约 定义。