HTML 海报生成
这个 Skill 只做一类事:用浏览器排版引擎生成可控海报,再导出 PNG / JPG。
默认判断:
- 正文、标题、标签、表格和 CTA 文案由 HTML/CSS 排版。
- 底纹、背景图、人物图、场景图、图标素材可以用 AI 生图或素材库生成。
- 不用 AI 生图直接生成带完整中文正文的最终海报。
- 不用 PIL / Canvas 手摆正文排版,PIL 只用于裁切、合成、压缩、预览和后处理。
触发场景
用户提到这些任务时使用:
- 做海报、生成海报、活动海报、报名海报、课程海报、听课海报、讲座海报。
- 做一张长图、宣传图、封面图,并且里面有较多中文信息。
- 改海报排版、海报文字挤、尾字堆叠、容器溢出、间距不对、对齐不稳。
- 明确说要 HTML 海报、前端排版、流式排版、pretext 文本预算、导出 PNG。
如果用户只要纯图像风格探索,使用当前环境已有的图像生成能力;横向翻页 PPT 或完整小红书发布包交给对应工具。本 Skill 不依赖其他私有 Skill,也不要求安装上述用途的工具才能制作海报。
运行环境与路径
本 Skill 可用于提供本地文件、命令执行和浏览器能力的 Agent 环境。先读取 README.md 的依赖说明,并检查 Python 3.10+、Python Playwright、Chromium 和可用中文字体。示例命令中的相对路径均相对于本 Skill 的安装目录;安装位置变化时,从实际加载的 SKILL.md 所在目录定位资源,不推测用户主目录。
已有依赖时直接复用。缺少依赖时报告具体缺项,按用户环境的安装权限处理;不自动修改全局环境。没有命令执行或浏览器能力时,可交付 HTML 草稿和待验收清单,必须标记“未渲染验收”,不能声称 PNG 已导出或最终交付通过。图片生成能力可选,无需 API Key 也能用 CSS 和 SVG 制作版式。
观点卡按用户给定的标题、核心观点、支撑点、行动和来源说明组织;用户要求逐字保留时不擅自缩写。画幅不足先报告预算冲突,再拆版或调整结构。
硬规则
1. 先预检,再执行
做海报前必须先完成一轮版式预检。预检不是形式表格,它要决定:
- 画幅和平台:如
1080×1440、1080×1920、1920×1080、2160×3840。 - 文案层级:主标题、副标题、解释文案、列表、时间地点、CTA、品牌尾注。
- 文本预算:每个文本槽位的最大行数、最小字号、最大高度。
- 字体策略:本地字体路径、字体栈、兜底字体、字重是否真的存在。
- 视觉职责:哪些是 HTML 文本,哪些是图片素材,哪些是图标。
- 安全区:边距、二维码区、底部尾注、平台裁切风险。
详细预检表见 references/poster-preflight.md。
2. 文本必须走流式排版
海报可以是固定画布,但文本内部必须走浏览器流式布局:
- 主体布局用 CSS Grid / Flex / normal flow。
- 每个文本区必须有真实宽度、最大行数或最大高度。
- 长标题先人工断行,再让 CSS 管细节。
- 列表、说明卡、流程卡、时间地点、二维码说明必须让浏览器自动换行。
- 固定坐标只允许用于画布、背景、装饰、图片槽、二维码槽、页脚这类外壳。
禁止:
- 给中文长句加
white-space: nowrap。 - 用负
letter-spacing、负margin、压行高来硬塞内容。 - 用
vw直接控制正文和按钮字号。 - 把同一张海报的文字拆成一堆绝对定位小块。
- 为了塞字把标题压到正文级别,或把正文压到不可读。
3. 图片只负责视觉,不负责正文
AI 生图、imagine、豆包、Seedream 适合做:
- 底纹、纸感、空间背景、人物氛围、局部图标、抽象物件。
- 没有精确中文正文要求的视觉主图。
不适合做:
- 带完整中文标题、课程信息、二维码说明的最终排版。
- 需要逐字正确、对齐稳定、可二次改文案的海报。
图标如果是通用含义,优先用 lucide / iconfont / SVG。只有品牌化、质感化、场景化图标才用 AI 生成,再嵌入 HTML。
4. 字体先验收再截图
中文海报默认优先使用:
- 标题衬线:
Source Han Serif SC、Noto Serif CJK SC、Songti SC。 - 正文无衬线:
Source Han Sans CN、Noto Sans CJK SC、PingFang SC。 - 不要混用一堆风格相近但指标不同的字体。
渲染前必须等:
await document.fonts.ready
如果用了 @font-face,路径必须能被浏览器访问。截图前用 getComputedStyle() 查一次关键文本实际字体,不能只看 CSS 写了什么。
5. 每次交付必须有截图验收
HTML 写完后至少做:
- 用 Playwright / Chromium 渲染目标尺寸截图。
- 检查关键文本没有
scrollWidth > clientWidth或scrollHeight > clientHeight。 - 检查
data-slot槽位没有越界、重叠、贴边。 - 检查二维码、CTA、时间地点、主标题可读。
- 输出一份
poster-layout-report.json或等价检查记录。
推荐命令:
python3 scripts/check_poster_layout.py \
./poster-project/poster.html \
--selector '#poster' \
--width 1080 \
--height 1440 \
--out ./poster-project/output
默认工作流
1. 复盘需求
先把用户输入整理成 poster-spec.json 或等价清单:
- 用途:招生、报名、会场引导、课程更新、听课提醒、产品介绍。
- 画幅:平台和像素尺寸。
- 文案:按层级拆好,不把长段原文直接塞进画布。
- 素材:人物、二维码、品牌 logo、背景、图标。
- 交付:HTML、PNG、JPG、源素材、预览图。
2. 版式预检
按 references/poster-preflight.md 做一轮判断。发现文案密度超标时,先删字、拆版或换版式,不进入 HTML 手调。
高风险信号:
- 主标题超过
18个中文字符还想一行放下。 - 一张
1080×1440海报塞5个以上信息区。 - 列表每条超过
22个中文字符。 - 课程 / 活动信息同时包含长标题、长副标题、讲师介绍、流程、二维码和大段说明。
- 用户要求“清晰”但给的是整段销售页文案。
3. 做 HTML
推荐结构:
<main id="poster" data-poster data-size="1080x1440">
<section class="hero" data-slot="hero">
<p class="eyebrow" data-fit="label">...</p>
<h1 class="title" data-fit="title">...</h1>
<p class="subtitle" data-fit="subtitle">...</p>
</section>
<section class="body-grid" data-slot="body">
...
</section>
<footer class="footer" data-slot="footer">...</footer>
</main>
CSS 要点:
#poster固定画布,内部槽位用 grid / flex。- 所有文本节点加
data-fit,复杂区域加data-slot。 - 主标题用明确
max-width、line-height、text-wrap: balance,必要时手动<br>。 - 卡片区使用
minmax(0, 1fr),防止长词撑破网格。 - 图片使用
object-fit: cover或contain,不要挤压变形。
4. 渲染与检查
先跑脚本,再肉眼看截图。脚本能抓机械问题,审美问题仍然要看图:
脚本输出的 status: pass 仅表示没有检测到 issues。仍须逐项复核 warnings(包括槽位重叠和贴边),并检查截图尺寸、文字内容、字体和图片清晰度。getComputedStyle() 返回的是声明字体栈,不能单独证明实际使用了哪一种字体;还需检查字体加载状态并观察截图,或使用浏览器字体检查能力。二维码的可扫描性须另行验证。
- 字体有没有变成系统兜底。
- 主标题、二维码、关键利益点是不是第一眼可读。
- 间距是否成体系,不是一处紧一处松。
- 视觉重心是否偏到边角。
- 中英文、数字、标点排版是否符合项目规则。
5. 返工记录
遇到返工,不写“优化清晰度”这种空话,记录成:
## Round 1
- 问题:副标题第 2 行尾字贴到右侧装饰线。
- 证据:output/check-01.png
- 修改:副标题槽宽从 820 改 760,行高从 1.35 改 1.42,装饰线移到独立 slot。
- 结果:通过。
交付结构
默认放在当前项目输出目录:
poster-project/
├── poster-spec.json
├── poster.html
├── assets/
├── output/
│ ├── poster.png
│ ├── poster-preview.png
│ └── poster-layout-report.json
└── layout-iteration-log.md
不要只交一个 PNG。只交 PNG 会把后续改字、换二维码、改时间地点都变成重新做图。
不通过就停
这些情况不能交付:
- 关键文字被裁切、压扁、重叠、贴边。
- 中文正文在 AI 生成图里,无法保证逐字正确。
- 字体没加载,截图用的是兜底字体。
- 二维码被压缩、模糊、边距不足。
- 没有 HTML 源文件,只有最终图片。
- 用户明确要可控排版,却继续用纯生图产出最终版。