Keyhtml — 神奇移动 HTML 演示文稿
制作单文件 HTML 演示文稿,支持翻页时跨页元素「神奇移动」。产出物是一个 HTML 文件:双击即放映,无外部依赖。方向键/滚轮/右侧圆点翻页,F 全屏。
「神奇移动」= 相邻两页的同名元素在翻页时自动补间飞行,即 Keynote 的招牌效果。基于浏览器原生 View Transitions API,不支持的浏览器自动回落为淡入淡出(Chrome/Edge/Safari 18+ 完整支持)。
一句话上手:复制 assets/template.html → 在里面创作幻灯片 → 浏览器打开验证。全部能力都由模板内置,你只写内容和过渡标记。
页数由内容决定,不是固定的。 模板里那些
<section class="slide">只是示范各种版式的样例——按用户实际内容自由增删:三页讲完就三页,要三十页就三十页。别被模板的页数框住,也别为了凑数保留用不到的示范页。
工作流
产出一份演示文稿的步骤:
- 先问用户选哪套主题(用户已指明则跳过)。动手前必须先问一句,给出三个选项让用户挑:
ink剧场墨黑(默认)——墨黑底 + 暖白正文 + 朱红强调,适合正式演讲、发布会midnight深空蓝——深蓝底 + 冷白 + 电蓝,适合科技、数据类主题paper浅色——米白底 + 深墨字 + 朱红,适合明亮场合、打印分享
- 复制
assets/template.html到目标位置并重命名(在副本上创作,别改模板原件),把第 2 行data-theme设为用户选的主题。 - 按用户内容决定页数:删掉用不到的示范页、复制需要的版式、增减
<section class="slide">——页数完全由内容定。需要新版式时在 LAYOUTS 段手写 CSS 类。 - 用下方「编排词汇」设计页间过渡,遵守「作者约定」。
- 在浏览器打开验证:每一组神奇移动必须正、反两个方向各测一遍——反向是正向的镜像,不是免费赠品;层级类 bug(闪烁)常只在反向出现。
模板里的 12 个 <section> 是版式样例库,不是固定篇幅:首页/目录/章节页/内容页/尾页各给了范例,还含三组可运行的神奇移动案例——P4→P5 容器变形、P7→P8 文字降级、P10→P11 图形缩放变色。用法是「挑需要的版式、按内容复制或删除」,而非照搬 12 页。拿不准某个效果怎么写,就读对应 <section>。
结构:一个引擎(勿动)+ 可选 + 可重写
模板分三段,只有一道硬边界——ENGINE 不可碰,其余随便改。区别在「怎么改」:THEME 是可选(拨开关,选预设),LAYOUTS 是可重写(做木工,手写版式)。
| 段 | 权限 | 内容 | 怎么动 |
|---|---|---|---|
| ENGINE | 🔒 勿动 | 翻页 + 神奇移动 + 回落(CSS 与 JS 各一段) | 禁止改动。修引擎=改模板发新版,不在单份演示文稿里 patch |
| THEME | ✎ 可选 | 颜色主题(多套预设)+ 字号阶梯 | 换肤只改 <html data-theme="..."> 一处,不用懂 CSS;见「主题切换」 |
| LAYOUTS | ✎ 可重写 | 版式类 | 按内容需要手写新类 + 对应结构,自由扩展 |
改颜色 / 字号在哪
全部集中在模板顶部 <style> 里的 THEME 段(注释 THEME — ✎ 可选 起,到 ENGINE — 🔒 引擎 止)。改这一段,不用碰 HTML 内容,也不用动引擎。
- 换整套配色 → 改第 2 行
<html data-theme="ink">的值(ink/midnight/paper),见「主题切换」。 - 调某个颜色 → 进 THEME 段找到对应
:root[data-theme="..."]{}块,改里面的颜色变量(如--accent强调色、--bg底色)。 - 调字号 → THEME 段末尾的
:root{ --fs-2xl … --fs-sm }那 5 行,见「字号阶梯」。
原则:颜色和字号一律改「变量的定义」(THEME 段),绝不在具体元素上写死 color: / font-size:——那样换肤和响应式都会失效。
主题切换
改文件第 2 行 <html lang="zh-CN" data-theme="ink"> 的 data-theme 值即可整体换肤,无需碰任何样式代码。预设三套:
| 值 | 名称 | 风格 |
|---|---|---|
ink | 剧场墨黑(默认) | 墨黑底 + 暖白正文 + 朱红强调 |
midnight | 深空蓝 | 深蓝底 + 冷白 + 电蓝 |
paper | 浅色 | 米白底 + 深墨字 + 朱红 |
新增主题:在 THEME 段照任意一套 :root[data-theme="名字"]{...} 复制改色即可。每套是一组颜色变量——正文三级(--text/--dim/--faint)、强调(--accent/--accent-soft)、描边(--line/--line-lit)、--strong(正文加粗字,浅色主题要设深色)、--overlay(浮层底)、--orb-* 与 --orb-warm-*(两组渐变球色)。LAYOUTS/ENGINE 层禁止写死颜色,一律走变量,否则换肤会漏色(如 --strong 写死 #fff 会在 paper 主题白底不可见)。字号阶梯所有主题共用、不随主题变。
字号阶梯(type scale · 5 级)
所有文字走这 5 个变量,禁止写死 font-size。命名从大到小、纯尺寸语义,方便排序与增减:
| 变量 | clamp 区间 | 用途 |
|---|---|---|
--fs-2xl | 46–100px | 封面 / 页面大标题 h1 |
--fs-xl | 32–58px | 内容页 / 章节标题 h2 |
--fs-lg | 20–30px | 卡片标题 / 目录主题 |
--fs-md | 15–19px | 正文 / 导语 / 详情行 |
--fs-sm | 13–16px | eyebrow / 注释 / 页码 / 标签 |
每级是 clamp(最小,理想vw,最大) 区间,字号随视口宽度平滑缩放并卡在上下限内——同一份演示文稿在笔记本/投影/大屏上视觉比例一致。
完整设计规范(颜色 + 字号 + 编排属性可视化)见 assets/design-spec.html,双击打开即可给团队看。
编排词汇(写在幻灯片元素上的属性)
前三个是神奇移动(翻页时跨页生效),data-rise 是页内入场:
| 属性 | 语义 | 用法 |
|---|---|---|
data-magic="id" | 飞:跨页配对补间 | 相邻两页元素写相同 id 即自动飞行;id 页内唯一 |
data-magic-shell | 变形:盒子真插值 | 加在纯盒子元素上,背景/描边/圆角/渐变做逐帧数值插值而非快照溶解 |
data-magic-fade | 溶解:脱离根快照 | 加在与飞行元素同页的普通内容上,引擎自动双向抬升到玻璃层独立淡出/淡入 |
data-rise="1..5" | 入场:依次上浮 | 进页时按序号依次上浮。带 data-magic 的元素引擎已自动禁用它,别同时依赖两者 |
data-magic-fade 与 data-rise 的分工:无飞行元素的普通页用 data-rise;一旦本页有元素在飞,想动的内容改用 data-magic-fade(否则被根快照冻结成硬切,见约定 7)。
右侧圆点分页器按 data-act="章节id" 自动分组:相邻 data-act 值不同处插入分隔线。给每个 <section> 标上所属章节(如 intro / c1 / c2 / end),同章节用同一个值;不标则并入上一章节。
图片放大是底层能力:给任意图片或图形容器加 class="zoomable" 即可点击放大(引擎内置灯箱,Esc / 点击任意处关闭)。<img> 取 data-full || src 作放大源,SVG 等非图片元素自动克隆展示。无需每份演示文稿重写灯箱。
运动缓动(两个 token,别一刀切)
Apple 演讲动效的分寸是「该弹的弹、该稳的稳」,引擎提供两个缓动变量:
| 变量 | 用途 |
|---|---|
--ease-smooth | 平滑减速。翻页、神奇移动的位置补间用它——大位移若过冲会显得晃、廉价 |
--ease-spring | 弹簧过冲。入场揭示(rise)、微缩放(图片 hover) 用它——落位轻弹一下,有生命感 |
扩展版式时遵守同一分寸:元素「出现 / 轻微缩放」可用 spring;元素「大距离移动」用 smooth。给所有运动无脑加过冲是新手翻车点。
作者约定(每条都是踩过的坑)
- 盒子即视觉。补间的是元素盒子而非文字。块级文字元素必须
width:fit-content,否则盒子撑满整行,飞行起点看起来在屏幕中心。 - 行内元素防碎片。
<span>类 magic 元素加display:inline-block,折行断片的元素无法被快照。 - 配对粒度是表达手段。文字对文字=概念延续(轻);容器对容器=对象变形(重);两者可同时用——命名的子元素会从父级快照中抠出独立飞行。
- 变形层模式。要真插值的卡片拆成「shell + 内容」两层:
<div class="shell 皮肤类" data-magic="id" data-magic-shell></div>绝对定位铺满作底,内容平级放其后。shell 必须是空盒子——它的快照被隐藏,内部任何内容会瞬间消失。 - 渐变过渡的条件。两侧渐变需同类型、同色标数(去掉颜色后字符串一致),引擎才做逐帧插值;纯色一侧可写成同色渐变来满足配对。不满足则硬切。
- 压盖内容标 fade。shell 起飞会把原本在它上面的兄弟内容压到玻璃底层造成闪烁,这些内容必须标
data-magic-fade。 - 同页普通内容也要标 fade 才有入场。神奇移动切页时,未标记的元素被打包进「根快照」整体交叉淡入,其
data-rise上浮会被冻结成硬切。所以:本页只要有元素在飞,其余想平滑进出的内容(正文、列表等)都改标data-magic-fade。 - 跳页同样触发。圆点导航跨页跳转也走配对检查,设计时不能假设只有相邻页会过渡。
设计哲学:为什么没有组件库
Keyhtml 刻意不提供卡片、按钮等组件库,这是核心设计决策,不是缺失。原则一句话:
固化正确性与功能性,开放品味与表达性;交付语法,而非词汇。
- 固化的(写进 ENGINE,勿动):翻页、神奇移动、字号阶梯、缓动、主题变量,以及分页器 / 灯箱 / 全屏这类功能性 UI——它们长什么样无所谓,做错了会坏。
- 开放的(交给作者):卡片、按钮等表达性元素——它们承载内容与个人品味,样子是审美判断,做"错"顶多不好看、不会坏。
不做组件库的理由:演示文稿要的是「每次都不同、服务当下叙事」,与产品 UI 追求的「一致、可复用」正相反。组件库在这里的维护成本随品味多样性发散、永远追不上,且只能拉齐水位、拉不出彩。
Keyhtml 给的是造词的语法而非现成的词:主题变量、字号阶梯、data-magic-shell 变形层、「盒子即视觉」等约定,不规定卡片长什么样,但保证你自己做的卡片能自动融入体系、参与神奇移动。跑得慢的照模板范例抄(有下限),跑得快的用语法自由发挥(无上限)。
给维护者:收到「加个组件库」类请求时,用上面的原则判断——若某元素是功能性、样子不影响表达,才考虑内置(像分页器那样);表达性元素一律交给作者。
设计指导(何时用、用多少)
减法优先——先想「这页能删到什么程度」
Apple keynote 的力量来自克制:一页常常只有一个词、一个物体。工具给了大字号能力,但默认不要把版面填满。
- 一页一个想法。敢让一句话、甚至一个词占满整屏(用
--fs-2xl+vcenter)。观众记住的是焦点,不是信息量。 - 封面那套 eyebrow + 标题 + 导语 + hint 是「上限」,不是「模板」。多数内容页删到只剩标题 + 一句话,甚至只剩标题,反而更有力。
- 有三个要点时,优先拆成三页,而不是一页并列三条——每页一个焦点,靠神奇移动串起来。
- 装饰服务内容:
hint、eyebrow 可留白省略;能用留白解决的,不要加线框和色块。
神奇移动
- 神奇移动是叙事工具:元素的连续性表达概念的连续性。典型场景——总览卡片收拢成详情页 tab、章节标题降级为角标、图形跨页生长。
- 相邻页没有概念关联时不要硬配对,默认的淡入淡出就是正确答案;引擎对无配对的翻页自动走经典转场,这是特性不是缺陷。
- 每次过渡聚焦一组主角,飞行的应是「同一个概念的一组元素」;满屏乱飞等于没有重点。
- 补间中的文字是快照交叉溶解(与 Keynote 一致),新旧字号差异越大溶解感越明显——两端大小悬殊时(如大标题落到小角标),优先用容器配对而非文字配对。