单页 HTML:需求原型 / 改动汇报
这是什么
**一页 HTML 讲清一件事。**不是界面图集,是「说明书 + 图」混排:该画的画出来、规则写旁边、这次改了啥标绿色。对方打开一个链接就能看懂、能评审、能拍板。
两种用法共用同一套地基(单文件、原型目录、8008 公网链接、?v=N、颜色语义、积木库),只是骨架不同:
| 用法 | 讲的是 | 读者 | 骨架在 |
|---|---|---|---|
| A. 需求原型 | 「要做成什么样」 | PM / 老板 | 本文件 §5 |
| B. 改动汇报 | 「已经做成了什么样,动了什么,谁受影响」 | 你自己 / 评审人 / PM | references/change-report.md |
~/www 下已经这么出过 29 个(2026-07 起),是团队出原型的主力路子。
先选路子:这个 skill 还是写真代码
| 情况 | 走哪个 |
|---|---|
| 讲需求、评审、拍板、贴 issue | 本 skill(默认) |
| 多个界面 + 规则说明 + 流转图 / 对比表混排 | 本 skill |
| 改前改后对比、方案 A/B 对比 | 本 skill |
| 汇报一次任务改了什么、影响什么 | 本 skill(模式 B) |
| 要真能点、能跳、走一遍主流程 | 写真代码的可交互原型 |
| 要 1:1 对齐生产端真实组件样式 | 写真代码的可交互原型 |
| 要入 git 让前端同事接着改 | 写真代码的可交互原型 |
拿不准就用本 skill:半小时出一版,改起来也快。可交互原型要写框架代码、编译、部署、提交分支,一版下来成本高一个量级。
环境自举(第一次用,或链接打不开时,先跑这个)
bash ~/.claude/skills/html-mockup/assets/bootstrap.sh
它会先判断这台要不要起 8008:
| 机器类型 | 起 8008 吗 | 原型走哪 |
|---|---|---|
| Coder 工作区(有公网端口转发) | 起 | preview_html 与 8008 按 §4.5 二选一 |
| mac 开发机 / 其它没有转发通道的机器 | 不起 | 一律 preview_html —— §4.5 的 ①② 在这台本来就做不到 |
没有转发通道的机器上,起了服务也只有同网段能看,还白占端口;积木库和模板直接读 assets/ 下的文件即可,不用起服务。真要局域网自用:PROTO_SERVE=1 bash .../bootstrap.sh。
起服务时它做五件事,幂等,重复跑安全:
- 建原型根目录(默认
~/www,已存在或已是软链则沿用) - 装 / 更新
_template/(起手模板)和_blocks/(积木库) - 起 8008 静态服务(
assets/serve.py,零依赖 stdlib,自带 no-cache) - 本地
curl自检 - 打印本机真实的 BASE_URL,末行形如
BASE_URL=https://8008--main--<workspace>--<owner>.<你的 Coder 域名>/
**永远用它打印的 BASE_URL,不要背域名。**每台机器的 workspace / owner 不同,写死的域名到别的机器上就是死链。脚本从 $VSCODE_PROXY_URI 推导,推导不出来才回落到 CODER_WORKSPACE_* 拼接。
给外部人(PM)之前必须做一次:Coder 端口转发默认 owner-only,别人打开是登录页(bootstrap 会探测并报出返回码,非 200 就是没放开)。工作区里的
coder是精简 agent 版,没有port-share子命令,只能去面板改:<你的 Coder 地址>/@<owner>/<workspace>→ Ports → 8008 → Share → Public。设一次就长期有效。
硬约束(环境定死的,不是风格问题)
- 单文件、零外部依赖。不引 CDN、不引 Google Fonts、不外链图片、不引 mermaid.js。端口转发带
Cross-Origin-Embedder-Policy: require-corp,跨源资源会被浏览器直接拦掉;国内网络加载 CDN 也会白屏。字体一律用系统字体栈(模板里已有),图标用 Unicode 字符(✓ ✕ › ▼ ☑ ⓘ ↻ ① ★)。 - 静态,不写交互。这是给人看的说明书,不是能点的 app。要能点就得写真代码。
- 原型目录不入 git,是孤本。机器重装、目录清理就没了 —— 需要长期留存的结论,写进 issue / PR / 知识库,别指望原型本身。
- 产物形态是
preview_html与 8008 二选一,判定见 §4.5。默认preview_html,只在它结构上做不到时才走 8008。
4.5 产物形态:preview_html 还是 8008(自动二选一)
**默认 preview_html。**它零部署、即时可见 —— 不用起服务、不用设 public、不用带 ?v=N、不用等对方点链接。
**只在下面四种情况让位给 8008。**前三条是 preview_html 结构上做不到的事,与内容长短无关;第四条才是体量问题:
| 情况 | 为什么 preview_html 不行 |
|---|---|
| ① 要给第三方看(PM、同事、贴进 issue) | 它只存在于当前对话,别人打不开 |
| ② 要留存、要改版迭代 | 它是一次性的:没有链接、没有 ?v=N、下一版无处可覆盖 |
| ③ 已经发过,用户说"只看到一半" | 确认被截断了,立刻改走 8008 重发链接 |
| ④ 内容确实很大(经验值 ≈50KB 以上) | 大概率触发截断,先走 8008 省一次来回 |
**「短内容才能用 preview_html」这条已废除。**中等篇幅的说明、单张界面帧、几节内容、单张 mermaid 黑底卡,直接 preview_html,不要因为"看起来有点长"就预先绕道 8008。
判定顺序:先看 ①②(意图),再看 ④(体量);③ 是事后信号。①② 命中就直接 8008,不必先试 preview_html。
⚠️ 50KB 是经验估计,不是实测值 —— skill 坑表只记了"出长原型被截断过",没记在多大体量翻的车。真遇到截断时记下当时的字节数,把这里的数字换成实测值。参考:模板 9KB、积木库 22KB、26 文件改动报告 59KB。
5. 模式 A:需求原型
A1. 定名 + 查有没有旧的
ls -d ~/www/*/ | rg -i "关键词"
同一个需求已有原型就改那一份,别新建。 对方手里的链接是旧的,新建一个他打不开。 真要废弃合并,在旧目录留一个 meta refresh 跳转页(见 §8)。
新建时目录名用功能英文短名(cost_recalc、brand_purchase_min_amount、invoice_archive),不带版本号、不带 issue 号。
A2. 拉真实素材,别凭印象画
动手前必须查到位,不然画出来的东西对方一眼看出不是他那个系统:
- issue 正文和评论的原话(
gh issue view) - 现在这个界面长什么样 —— 去前端仓库找对应页面,或看对方给的截图
- 涉及的字段、状态、口径 —— 去后端仓库核实,别编字段名
术语按系统真名:「物品」不叫「商品」,「外部采购 / 调拨 / 品牌采购」用系统里的原名。
A3. 拼页面
必须从 ~/www/_template/index.html 复制起手。
⚠️ 不要照着旧页面抄 CSS。旧页面带着它生成那天的字号、宽度、缺失的
.bleed—— 抄过来就把过时样式一起继承了,而且页面看着正常,没人会发现。实测:模板已 16px,照旧页抄出来仍是 14px。 模板是唯一起点;旧页面只能抄内容结构(哪些节、什么顺序),不抄<style>。
骨架固定这几块:
- 页头 — 功能名 + 一句话说清这版讲什么 + 日期
- sticky 锚点导航 — 界面超过 3 个必加,读者靠它跳
- 「本次更新」绿框 — 第二版起必加,列这次改了几条,每条带锚点跳过去
- 分节 — 一节一件事,
.st-h编号标题 +<small>「从哪进 / 什么时候看到」,复杂的节再加一句.lead副标题定调 - 说明块 — 规则写
.hint块里,别塞进界面冒充 UI 文案
节里放什么,从 ~/www/_blocks/index.html 抄。先按「要表达什么」选积木,别一上来就画界面 —— 很多需求用流转图 / 矩阵表 / 时间线讲比堆界面清楚得多。积木索引见 references/blocks.md。
A4. 本地验
# 有 mermaid 卡就先渲染,再验(顺序不能反,渲染会改文件)
python3 ~/.claude/skills/html-mockup/assets/render-mermaid.py <目录>/index.html
# 横向溢出:页面上看不出来,不量就发现不了
python3 ~/.claude/skills/html-mockup/assets/check-overflow.py <目录>/index.html
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8008/<feature>/
不是 200 就重跑 bootstrap.sh(Coder 工作区重启后服务会掉)。
grep -c '<svg' <目录>/index.html 要等于 .mmd 卡片数,不等就是有图没渲出来。
check-overflow.py 报撑破就照 §7「宽度」给那几个元素加 .bleed。
改已有页面时,先把它对齐到当前模板(幂等,重复跑安全):
python3 ~/.claude/skills/html-mockup/assets/align-page.py <目录>/index.html
它补两样:字号阶梯(对齐 16px 正文)、布局兜底 CSS(.bleed / .mmd 横滚 / code 断行 / table.cmp 横滚 / dd dt 的 min-width:0)。内联 SVG 一律跳过并断言前后一致。
跑完必须再跑一次 check-overflow.py —— 字号变大会把并排双栏、宽表撑得更宽。
A5. 交付链接
<BASE_URL><feature>/?v=N
- 必须给 bootstrap 打印的公网地址,不能给
localhost:8008或内网 IP —— 对方在自己电脑上打不开。 - 改过就带
?v=N破缓存(每改一版 N+1)。不带的话对方看到的还是旧的。 - 能直接给锚点:
.../cost_recalc/?v=3#s4跳到第 4 个界面。 - 交付前
curl公网地址确认 200 再发。
交付话术:永远把完整 URL 明文写出来
只要有地址,就把地址完整贴出来,不要用 [文字](url) 把它藏在链接文字后面 —— 那样读者没法复制、没法转发、也不知道自己要打开的是哪台机器的哪个原型。裸 URL 在 markdown 里本来就是可点的,明文和可点两者不冲突。
✅ 正确:地址明文,一眼能看见、能复制
跨店分页改动汇报:
https://8008--main--myws--alice.coder.example.com/cost_recalc/?v=2
本次更新 3 条,顶上绿框里,点条目能跳到对应界面
❌ 错误:地址被藏起来了
[打开改动汇报](https://8008--main--...)
点这里查看原型
别嵌 iframe、别用 preview_html 再包一层。锚点也直接写进 URL:...?v=3#s4。
6. 模式 B:改动汇报
触发:「总结一下当前任务的所有改动」「这次改了什么」「出个变更说明」「动了哪些表 / 业务规则」。
**完整执行手册在 references/change-report.md,做之前必须读。**这里只放不能违反的铁律:
- **不漏。**以
git diff --stat的文件清单为唯一底账,每个文件都要出现在 S1 的 ASCII 树里(带 ±行数和一句话注释)。收尾跑覆盖率自检:底账文件数 == 树里出现的文件数,差一个都要补。 - **逐行看,不看摘要。**每一行改动都要回答「它动了哪条原有业务规则」。没动规则的行归为「无规则影响」,也要显式说出来,不能沉默跳过。
- 分派多个代理并行采集,六条线同时跑(diff 清点 / 数据库字段 / 业务规则逐行 / 影响面与调用方 / 文案与 i18n / 测试与风险)。手册里有现成的分工提示词。
- **大白话优先。**每一节开头先用一句人话说结论,再上表格和图。别让读者自己从 diff 里悟。
- 必须有的四块内容:动了哪些表字段、改了哪些原有业务规则(原规则 → 新规则 → 触发条件 → 谁受影响)、影响哪些业务点、回滚怎么做。
5.5 每条改动都要落到「页面 → 操作 → 结果」,并且把页面画出来:
- 页面:用户实际看到的那一屏,用积木库的界面帧 / 后台外壳 / 列表页 / 小票画出来 —— 不是描述,是画。
- 操作:在这一屏上做什么(点哪个按钮、填什么、选哪个筛选、翻到第几页)。
- 结果:改前会怎样 → 改后会怎样。界面怎么变、数据怎么变、谁什么时候能感知到。 用户侧真的无感知时,明确写一句「用户无感知,仅 xxx 变化」,不要跳过这一节。 Why:只写"改了 xxx 函数的判断条件",读者无法验收、测试无法复现;落到页面和操作,PM 能验、测试能复现,你自己也会发现"这个改动用户其实碰不到"。
- 图的分工:结构和清单用 ASCII(见 §7),状态流转和调用链用 mermaid 黑底(见 §7),界面变化用积木库的双栏对照。
7. 视觉规范
字号:正文 16px 起,别更小
模板的字号阶梯(2026-08-16 连上调两档,原来 14px 正文明显偏小):
| 用途 | 字号 |
|---|---|
正文 body |
16px |
节标题 .st-h |
18px |
说明块 .say / .hint / .lead / 规则卡正文 |
15px |
表格 td / th |
14px |
行内 code、小标签 |
12.5~13px |
辅助文字(small、.stats .l) |
11~12px |
中文比拉丁字母更吃字号,13~14px 的说明块在 900px 栏里读着累。加大字号还顺带把行长拉回来(14px 时 62 字/行 → 16px 时 54 字/行)。
**下限就是 16px,不要再往回调。**要更紧凑就减内容,不是缩字。
⚠️ **改字号时必须跳过内联 SVG。**mermaid 渲出来的 SVG 里节点框尺寸是渲染那一刻烤死的,字号一改文字就顶出框被裁(实测「700 个文件提交掉」变成「提交挂」、「canary 跑迁移演练」被切掉两字)。批量调字号要先把
<svg>…</svg>抠成占位符,改完再放回去。图要变大就重跑render-mermaid.py,不要动 SVG 里的 CSS。
宽度:按页面类型选档,同一页内不许出现断层
先按页面类型定正文栏,再谈宽内容。
| 页面类型 | 正文栏 | 判断依据 |
|---|---|---|
| 模式 A 需求原型(界面帧 + 说明为主) | .wrap 900px |
主体是散文和单个界面帧,16px 下 54 汉字/行 |
| 模式 B 改动汇报 / 调查报告(规则卡 + 表格 + 并排双栏为主) | .wrap rep 自适应 clamp(900px, calc(100vw - 64px), 1920px) |
主体不是散文,900 装不下;跟着屏幕长,不浪费空间 |
| 画完整后台外壳的原型 | .wrap desk 1180px |
后台界面本身就宽 |
<div class="wrap rep"> <!-- 模式 B 一律加 rep -->
报告档是自适应的,所以 .bleed 在它里面不再挣脱(width:100%)—— 外壳已经跟着屏幕长了,再挣脱只会让左边缘错位 49px。.bleed 只在模式 A 的 900 栏里才需要挣脱(上限 1440px)。
文字块单独收住行长:.rule dd / .uv / .say / .hint / .lead 加 max-width:52em(≈48 汉字/行)。这是自适应能成立的关键 —— 不收的话 2560 屏上正文会变成 87 汉字/行。收完的效果是「正文一列、图表更宽」,左边缘全部对齐,右边缘错开,读起来像正常文档。
实测同一页在三种屏幕上:正文栏 1216 / 1504 / 1920px,并排双栏 599 / 663 / 871px 各一屏,文字始终 48 汉字/行。
⚠️ 别单独优化每一块,要看它们上下摞在一起是什么样。
这是翻过车的:按行长把正文栏定 900、按装得下把
.bleed定 1400,每块单独看都对,摞在同一页就是断的 —— 规则卡文字挤在 701px,紧贴的双栏铺开 1400px,左侧 250px 死白。行长规则管的是段落散文,而这类页面主体是规则卡、表格、代码引用,散文只占一小部分,用错了地方。判断标准:同一页里最窄的内容块和最宽的内容块,差距不该超过一档(现在是 1280 vs 1440,差 160px,看不出来)。
收尾必跑(页面上看不出来,不量就发现不了):
python3 ~/.claude/skills/html-mockup/assets/check-overflow.py <目录>/index.html
多视口检测横向溢出。模板已内置这几条兜底,别删:
| 兜底 | 挡住什么 |
|---|---|
.wrap{overflow-wrap:break-word} |
裸长标识符(没包 <code>)撑破整页 |
code{overflow-wrap:anywhere} |
长表名 / 带下划线的字段名 |
@media(max-width:900px){.wrap table{display:block;overflow-x:auto}} |
窄屏下宽表 —— 逐个枚举 .cmp/.mx/.dt 挡不住 |
.wrap dd,.wrap dt,.wrap dl > *{min-width:0} |
grid 子项的 min-width:auto 不肯收缩到轨道宽度 |
.mmd{overflow-x:auto} |
宽图没容器兜 |
架构图要更高规格时(可选)
改动汇报里的配图用 mermaid 就够。只有「图本身就是交付物」(架构评审、给外部看的系统地图)才值得升级到 archify —— 它渲染前用 schema + 布局约束校验,视觉高一档,但只有 sequence 几乎零成本,workflow 中文塞不进去。
用之前读 references/archify.md(四种图型的实测成本、boundary 的坑、合并 tab 页的做法、源码引用怎么挂)。
颜色是有意义的,别乱用
| 用法 | 颜色 |
|---|---|
| 现状、已有的 | 灰白常规样式 |
| 这次新增 / 改的 | 绿色 #16a34a(.tag-new 徽标 / .newf 绿虚线框) |
| 主操作按钮 | 琥珀 #f59e0b(默认主色,按你自家产品调) |
| 编号、强调 | 橙 #ea580c |
| 警告 / 失败 / 破坏性 | 红 #dc2626 |
| 删除掉的 | 红色 + 删除线 |
读者看原型第一件事是分清「哪些是现在就有的、哪些是这次要加的」。绿色标记就是干这个的。
ASCII 图:只用半角
中文是双宽字符,和半角混排必然错位,浏览器字体一换更歪。
- 框线里只放半角:表名、字段名、文件名、类名本来就是英文,直接用。
- 中文说明放框外,或用框内右侧
# 注释形式单独成列,不参与对齐。 - ASCII 块必须包在
<pre class="ascii">里(模板已带等宽字体 + 深灰底 + 横向滚动),不要放进普通<div>。 - 树用
├─ └─ │,箭头用→ ←,层级缩进 2 空格。
order_pay
├─ pay_amount decimal(10,2) unchanged
├─ discount_amount decimal(10,2) unchanged
└─ coupon_deduct decimal(10,2) NEW # 券抵扣额,新增
mermaid:唯一用黑底的地方,而且必须渲染成图
页面整体是浅色,只有 mermaid 图用黑底,让它在一片白里一眼跳出来。
**写完源码卡不算完 —— 必须跑渲染器。**只贴源码等于没画:手机上是一坨代码,读者不会自己粘到别处渲染。
每张图的源码第一行必须带这段主题(渲染出来才是黑底):
%%{init:{'theme':'base','themeVariables':{'background':'#0b0f14','primaryColor':'#111827','primaryTextColor':'#e5e7eb','primaryBorderColor':'#334155','lineColor':'#64748b','secondaryColor':'#1e293b','tertiaryColor':'#0f172a','fontFamily':'ui-monospace,SFMono-Regular,Menlo,monospace'}}}%%
先按积木库 _blocks 的 .mmd 卡片写源码,页面写完后收尾时跑一次:
python3 ~/.claude/skills/html-mockup/assets/render-mermaid.py ~/www/<页面>/index.html
# 多个页面可一次传多个;--force 强制重渲(改了源码后用)
它做四件事:①mmdc 渲成 SVG 内联进 HTML(SVG 是纯文本,不违反单文件约束,不需要 CDN);②源码收进 <details> 折叠,仍可复制去 issue / PR;③按 viewBox 宽度分档 —— ≤900px 撑满容器(.mmd fit),>900px 保持原尺寸 + 横向滚动 + "可左右滑动"提示(.mmd wide),这是手机上宽图不被压成蚂蚁字的关键;④幂等,重复跑只重算尺寸不重渲。
依赖是 @mermaid-js/mermaid-cli + 系统 chrome。缺依赖时它保持源码卡原样、不会改坏页面,但那样图就没画出来 —— 先装:
npx --no-install mmdc --version || npm i -g @mermaid-js/mermaid-cli # 需要 google-chrome/chromium
渲染器内部已用 PUPPETEER_EXECUTABLE_PATH 指向系统 chrome —— 不这么做 puppeteer 会去找自己缓存的特定版本然后报 Could not find Chrome (ver. …)。
收尾自检:grep -c '<svg' 页面 的数量要等于 .mmd 卡片数;还剩几张没渲染就是几张图读者看不到。
8. 合并 / 废弃旧原型
旧目录 index.html 换成跳转页,对方手里的旧链接照样能用:
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=../invoice_archive/?v=7#r1">
<title>已合并</title></head>
<body style="font-family:sans-serif;padding:40px;color:#555">
原型已合并到一页,正在跳转… <a href="../invoice_archive/?v=7#r1">点此打开</a>
</body></html>
9. 坑(全是真翻过车的)
| 坑 | 后果 | 正确做法 |
|---|---|---|
写死 8008--main--myws--alice... 这类域名 |
换台机器就是死链 | 用 bootstrap.sh 打印的 BASE_URL |
| 因为"内容看起来有点长"就绕开 preview_html 直接走 8008 | 白起服务、白设 public、白等对方点链接,自己也多花一轮 | 默认 preview_html;只有 §4.5 那四种情况才走 8008 |
| 内容很大(≈50KB+)还硬用 preview_html | 被截断,对方只看到一半 | 命中 §4.5 第 ④ 条就直接走 8008;已经发出去才发现截断,立刻补一个 8008 链接 |
| 给 localhost 或内网 IP | 对方打不开 | 给公网 BASE_URL,且确认端口已 share 成 public |
改完原地覆盖不带 ?v=N |
对方看到的是旧版,以为没改 | 每版 N+1 |
| 引 CDN 字体 / 外链图 / mermaid.js | 白屏或资源被 COEP 拦掉 | 系统字体栈 + Unicode 图标,单文件自包含 |
| ASCII 框线里混中文 | 浏览器里必然错位 | 框内只放半角,中文放框外 |
| 要截图 / 转 PDF 时用了彩色 emoji(🆕 ✅ 🔁) | 这台机器没 emoji 字体,渲出来是豆腐块 □ | 看链接没问题;只要截图或转 PDF,就换成 Unicode 符号(① ★ ▼ › ⓘ ✓ ✕ ☑ 实测正常) |
| 从积木库抄了两个积木,样式互相串了 | 后代选择器压不住顶层同名类:写了 .mx .note 也照样吃到 .note 的橙边框 |
抄之前先搜一遍类名有没有撞。已知三处已在积木库里改好名:列表页表格 .dt(非 .tb)、小票小计 .amt(非 .st)、矩阵说明列 .rmk(非 .note) |
mermaid 源码里的 <br/> 直接写进 <pre> |
浏览器把它当成真的换行标签渲染掉,读者复制走的源码缺了 <br/>,贴到 issue 里节点不换行 |
写成 <br/>。收尾用 HTMLParser 扫一遍,</br> 栈顶是 <pre> 这类报错就是它 |
| 删一处规则后,只在「改的那份文件」里查残留 | 同一条规则往往写在多份文档里,漏掉的那份会长期指错。删「逐文件清单」时只查了 SKILL.md 和 change-report.md,README 里那句「逐文件交代」挂了三次删除都没发现 —— 而 README 恰恰是给外部人看的门面 | 删规则要全仓 grep,不是只查手上那份 |
| 搜残留只用一种写法 | 同一个概念常有多种写法,只搜一种必然漏。实测:改「九节→八节」时按中文数字搜,README 里写的是阿拉伯数字「9 节」,没搜到;脱敏时 grep -E ttpos 报 0 处,换 -i 才发现大写 TTPOS |
中文/阿拉伯数字、大小写、全角/半角一起搜;清理审计类扫描一律加 -i |
| 循环里改字符串,却用循环前算好的偏移量 | 第一次插入后,后面所有 match.start() 全错位 —— 实测只处理了 5 个中的 2 个,而且不报错 |
倒序处理(reversed(list(re.finditer(...)))),earlier 偏移量才不受影响 |
把 <a href="https://…"> 也算成「违反单文件约束」 |
自检误报。单文件约束管的是资源加载(CSS/字体/图片会被 COEP 拦),<a href> 是导航,两回事 |
检查只匹配 <link>/<script>/<img>/<iframe> 的 href/src |
拼接时既用了自带结尾换行的常量,又手动补 "\n" |
首次注入是两个换行、后续替换只剩一个 —— 第二遍跑就少一行,不幂等且不报错。实测 render-mermaid.py 这么错过 |
常量统一 .rstrip("\n") 后再拼;幂等性要连跑三遍比 md5,跑一遍看不出来 |
工具把自己的 CSS 塞进页面已有的 <style>,再用「标记 → </style>」范围替换来更新 |
把标记之后、</style> 之前的用户 CSS 全吃掉 —— 页面看着正常,只是布局悄悄退回旧样子 |
工具的产物独占一个容器(自己的 <style data-xxx> / 自己的文件 / 成对哨兵),整块替换 |
拿输出文件名或工具产物的 <title> 当标题 |
输出叫 index.html 时标题就成了「index」;工具的 <title> 常带自己的尾巴 |
文件名是 index 时退回目录名,或显式传标题;已知尾缀剥掉 |
用 XML 解析器(ElementTree)验含内联 SVG 的页面 |
报 not well-formed (invalid token) —— 但页面完全正常。archify 之类的工具会输出无值布尔属性(<text data-detail-anchor x=…>),HTML5 合法、XML 不合法 |
**含内联 SVG 的页面不能用 XML 解析器验。**用 HTMLParser(见下条)或直接浏览器测量。这已是同类假报错第三次:</path> 栈顶 <marker>、scrollWidth > foreignObject width、本条 |
合并多份工具产物时不给 <button> 写 color:inherit |
深色主题下 tab 文字是黑字,几乎看不见 —— <button> 默认不继承父级 color,用的是浏览器默认色 |
凡是 background:none;border:0 的按钮,必须显式 color:inherit |
| 用 HTMLParser 扫含内联 SVG 的页面 | 一堆 </path> 栈顶 <marker> 假报错 —— SVG 的 <path> 是配对写法,不是 HTML 空元素 |
内联 SVG 单独用 ElementTree.fromstring 验;HTMLParser 扫剩下的部分 |
| 图上留讲解标注、写「保持原样」清单 | 对方以为那些字是界面上的 | 界面帧里只放界面上真有的字,解释放 .hint 块 |
| 跟人说「图 1 / 图 2」 | 对方不知道你指哪个 | 说界面名字,或直接给锚点链接 |
| 凭印象画现有界面 | 对方一眼看出不是他的系统,白做 | 先去代码 / 截图核对真实样子和字段名 |
| 术语写「商品」「内部编码」 | 跟系统对不上 | 用「物品」「物品编码」等系统真名 |
| 同需求新建一个目录 | 对方手里旧链接还是旧内容 | 改原目录;废弃的留 meta refresh 跳转 |
| 改动汇报只讲改了什么、不讲影响谁 | 评审看不出风险,等于没审 | 表字段 / 业务规则 / 业务点 / 回滚,四块缺一不可 |
10. desktop 原型
shop 后台页(网页版)要套完整后台壳,别用移动式窄卡片:.wrap 放宽到 1180,画出左侧菜单 + 顶栏 + 内容区三段,橙色主题。参照积木 A(桌面后台外壳)。
11. 参考现成的
| 位置 | 看什么 |
|---|---|
~/www/_blocks/ |
积木库,浏览器直接打开 <BASE_URL>_blocks/ |
~/www/_template/ |
空白起手模板,<BASE_URL>_template/ |
references/blocks.md |
积木索引:「要表达什么」→「用哪个积木」 |
references/change-report.md |
模式 B 完整手册:多代理分工 + 八节骨架 + 逐行规则比对 |
assets/bootstrap.sh |
环境自举(建目录 / 装模板 / 起 8008 / 打印 BASE_URL) |