html-slides
用一个手写的单文件 HTML 制作会议级演示文稿。方法源自 Han Xiao(Jina AI)的 公开演讲 deck(如 hanxiao.io/aie-sf-2026):无框架、无构建步骤,浏览器直接 打开放映,Chrome 打印导出 PDF 交付会务。
When To Use
- 需要视觉风格完全可控、能在线分享(一个 URL)的演讲 slides
- 需要图表标注与正文风格像素级统一(手写 SVG,而非图表库截图)
- 不适用:需要多人协作编辑的场景用 PPT/Slides;内容型交互网页用
interactive-html;学术 beamer 需求用rhetoric-of-decks
叙事与修辞(标题写论断、一张 slide 一个想法、三幕结构)遵循
rhetoric-of-decks 的原则,本 skill 只负责"HTML 这种载体怎么做"。
核心机制(不可省略的三件事)
- 固定舞台 + 等比缩放:
#stage固定 1280×720,所有排版用绝对 px; JS 按min(vw/1280, vh/720)缩放整个舞台。绝不写响应式断点—— 固定坐标系是排版永不破版的前提。 - 设计 token + 语义组件:颜色只在
:root定义,纪律是"颜色即 角色"——每个语义色全场固定代表一个叙事角色,语义色不超过 3 个; 每种修辞成分一个 class(金句、对比卡片、流程图、大数字、 三线表……),slide 内不写内联颜色和字号。 - 图表手写 SVG:用 15 行工具箱(
el/txt/mount)逐图绘制, 数据放独立的data.js。不用图表库——风格统一和图内结论性标注是 这套方法的核心卖点。
完整机制拆解(导航、深链接、CSS 动画、打印适配、手机遥控)见
references/anatomy.md。
Workflow
- 大纲先行:每张 slide 写一句论断式标题(不是"结果"而是"X 提升了
61%"),排出三幕结构,并按
references/design-catalog.md的 内容→组件决策表为每页标注版式。自检信号(非硬性):纯文字版式 连排多页时停下来问一遍——这些内容的形态是不是其实是对比/趋势/ 流程,能画就画。大纲连同版式标注一起与用户确认后再动手。 - 起步模板:复制
assets/template.html到工作目录,重命名为index.html。模板内置 6 种版式(标题页/编号要点/对比卡片/流程图+ 大数字/SVG 折线图/金句结尾)。 - 定设计 token:优先从
references/design-catalog.md的主题预设 起步(默认 warm-cream 暖米+橙;另有 elastic-blue),或按用户品牌改:root变量。颜色即角色:--accent/--foil/--teal只是默认 角色位(主角/对照/中性),按主题实际分配——无对抗性的主题--foil可整场缺席;角色多于 3 个时不加第四色,改用分组或同色 深浅(见 design-catalog §4)。不要引入灰色文字——层级靠字号和 字重区分。 - 逐张生成 slide:每张一个
<section class="slide">,只用语义组件 拼装。缺组件时先看references/anatomy.md的组件清单;确实没有就 按references/design-catalog.md§4 的生成语法造新组件——符合语法 的新组件天然和全场和谐(样式进<style>统一管理,不写内联)。 - 图表:先在
references/design-catalog.md的配方库里选图型 (折线/分组柱状/堆叠条/坡度图/热力图/散点/时间轴/盒线图)。数据写进data.js(const DATA = {...}),每图一个drawXxx()函数挂到对应 容器 id。坐标轴刻度、单位、图内 legend、结论性标注(直接写在数据点旁) 都要有;legend 放数据空白区,截图确认不与数据重叠。 - 验证:用
scripts/screenshot.sh <file> <页码...>无头截图逐张检查 溢出与对齐(内容超出 720px 高度是最常见问题)。有 figure-checker 可用时交给它做视觉 QA。 - 交付:告知用户放映方式(浏览器打开,方向键翻页、
f全屏、 点击左 1/3 后退右 2/3 前进、#N跳页);需要 PDF 时 Chrome 打印、 纸张自定义 1280×720px、无边距。需要手机遥控翻页时按references/anatomy.md的 sync 方案加装。
常见坑
- 字号低于 13px 在投影上不可读;正文不小于 16px
- 每张 slide 内容超出 720px 不会滚动,只会被裁掉——宁可拆页
@media print里必须关闭所有动画,否则 PDF 导出会截到中间帧- MathJax 只在确有公式时引入(本地 vendor 文件,不走 CDN)
.kicker/.tag等 mono 标签常带text-transform:uppercase,会把 希腊字母 τ/π 转成大写破坏数学记号——含公式符号的标签要加text-transform:none