HTML PPT Studio — author professional static HTML presentations in many styles, layouts, and animations, all driven by templates. Use when the user asks for a p
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-html-ppt-skill-487742b74451 ,按照其中的说明把「html-ppt」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Author professional HTML presentations as static files. One theme file = one
look. One layout file = one page type. One animation class = one entry effect.
All pages share a token-based design system in assets/base.css.
npx skills add https://github.com/lewislulu/html-ppt-skill
One command, no build. Pure static HTML/CSS/JS with only CDN webfonts.
No network on the target machine? Point the CLI at a local copy
(npx skills add ./html-ppt-skill), or just copy this folder into your agent's
skills directory — ~/.claude/skills/html-ppt/ for Claude Code. Decks render
offline; only the webfonts fall back to the system stack. See
README.md.
assets/themes/*.css) — minimal-white, editorial-serif, soft-pastel, sharp-mono, arctic-cool, sunset-warm, catppuccin-latte/mocha, dracula, tokyo-night, nord, solarized-light, gruvbox-dark, rose-pine, neo-brutalism, glassmorphism, bauhaus, swiss-grid, terminal-green, xiaohongshu-white, rainbow-gradient, aurora, blueprint, memphis-pop, cyberpunk-neon, y2k-chrome, retro-tv, japanese-minimal, vaporwave, midcentury, corporate-clean, academic-paper, news-broadcast, pitch-deck-vc, magazine-bold, engineering-whiteprinttemplates/full-decks/<name>/) — complete multi-slide decks with scoped .tpl-<name> CSS. 8 extracted from real-world decks (xhs-white-editorial, graphify-dark-graph, knowledge-arch-blueprint, hermes-cyber-terminal, obsidian-claude-gradient, testing-safety-alert, xhs-pastel-card, dir-key-nav-minimal), 7 scenario scaffolds (pitch-deck, product-launch, tech-sharing, weekly-report, xhs-post 3:4, course-module, presenter-mode-reveal — 演讲者模式专用)templates/single-page/*.html) with realistic demo data, including 5 real-image layouts (single / full-bleed / image+text / gallery / before-after)assets/animations/animations.css) via data-animassets/animations/fx/*.js) via data-fx — particle-burst, confetti-cannon, firework, starfield, matrix-rain, knowledge-graph (force-directed), neural-net (pulses), constellation, orbit-ring, galaxy-swirl, word-cascade, letter-explode, chain-react, magnetic-field, data-stream, gradient-blob, sparkle-trail, shockwave, typewriter-multi, counter-explosionassets/runtime.js) — arrows, T (theme), A (anim), F/O, S (presenter mode: magnetic-card popup with CURRENT / NEXT / SCRIPT / TIMER cards), N (notes drawer), R (reset timer in presenter)assets/animations/fx-runtime.js) — auto-inits [data-fx] on slide enter, cleans up on leaveUse when the user asks for any kind of slide-based output or wants to turn text/notes into a presentable deck. Prefer this over building from scratch.
If the user mentions any of: 演讲 / 分享 / 讲稿 / 逐字稿 / speaker notes / presenter view / 演讲者视图 / 提词器, or says things like "我要去给团队讲 xxx", "要做一场技术分享", "怕讲不流畅", "想要一份带逐字稿的 PPT" — use the presenter-mode-reveal full-deck template and write 150–300 words of 逐字稿 in each slide's <aside class="notes">.
See references/presenter-mode.md for the full authoring guide including the 3 rules of speaker script writing:
All full-deck templates support the S key presenter mode (it's built into runtime.js). S opens a new popup window with 4 magnetic cards:
Each card is draggable by its header and resizable by the bottom-right corner handle. Card positions/sizes persist to localStorage per deck. A "Reset layout" button restores the default arrangement.
Why the previews are pixel-perfect: each preview is an <iframe> that loads the actual deck HTML with a ?preview=N query param; runtime.js detects this and renders only slide N with no chrome. So the preview uses the same CSS, theme, fonts, and viewport as the audience view — colors and layout are guaranteed identical.
Smooth navigation: on slide change, the presenter window sends postMessage({type:'preview-goto', idx:N}) to each iframe. The iframe just toggles .is-active between slides — no reload, no flicker. The two windows also stay in sync via BroadcastChannel.
Only presenter-mode-reveal is designed from the ground up around the feature with proper example 逐字稿 on every slide.
Keyboard in presenter window: ← → navigate (syncs audience) · R reset timer · Esc close popup.
Keyboard in audience window: S open presenter · T cycle theme · ← → navigate (syncs presenter) · F fullscreen · O overview.
Do not start writing slides until you understand three things. Either ask the user directly, or — if they already handed you rich content — propose a tasteful default and confirm.
pitch-deck-vc, corporate-clean, swiss-gridtokyo-night, dracula, catppuccin-mocha,
terminal-green, blueprintxiaohongshu-white, soft-pastel, rainbow-gradient,
magazine-boldacademic-paper, editorial-serif, minimal-whitecyberpunk-neon, vaporwave, y2k-chrome,
neo-brutalismtemplates/full-decks/<name>/ and ask if it fits. If the
user's content suggests something obvious (e.g. "我要做产品发布会" →
product-launch), propose it confidently instead of asking blindly.A good opening message looks like:
我可以给你做这份 PPT!先确认三件事:
- 大致内容 / 页数 / 观众是谁?
- 风格偏好?我建议从这 3 个主题里选一个:
tokyo-night(技术分享默认好看)、xiaohongshu-white(小红书风)、corporate-clean(正式汇报)。- 要不要用我现成的
tech-sharing全 deck 模板打底?
Only after those are clear, scaffold the deck and start writing.
./scripts/new-deck.sh my-talk
open examples/my-talk/index.html
T to cycle. Or hard-code it
(../assets/ here is a placeholder — use whatever prefix the rest of the
file already uses; new-deck.sh has set it to the right depth):
<link rel="stylesheet" id="theme-link" href="../assets/themes/aurora.css">
Catalog in references/themes.md.<section class="slide">...</section> blocks out of
files in templates/single-page/ into your deck. Replace the demo data.
Catalog in references/layouts.md.data-anim="fade-up" (or class="anim-fade-up") on
any element. On <ul>/grids, use anim-stagger-list for sequenced reveals.
For canvas FX, use <div data-fx="knowledge-graph">...</div> and include
<script src="../assets/animations/fx-runtime.js"></script>.
Catalog in references/animations.md.../../../assets/ is relative to its own location, so a
manual copy lands the paths at the wrong depth:
./scripts/new-deck.sh my-talk -t pitch-deck
Each folder is self-contained with scoped CSS. Catalog in
references/full-decks.md and gallery at
templates/full-decks-index.html../scripts/render.sh templates/theme-showcase.html # one shot
./scripts/render.sh examples/my-talk/index.html 12 # 12 slides
templates/single-page/ first, then replace content.assets/base.css and overridden by a theme.
Good: color: var(--text-1). Bad: color: #111.
Text on top of an --accent fill is the one people get wrong: it needs
color: var(--accent-ink), because accents here run from #ffffff to
#000000 and no literal ink is readable on all of them.templates/single-page/*.html if none of the 36 fit.image-* layouts and
use .img-frame — see Images below. Never drop a bare <img> into a slide:
an unframed image ignores the slide's height and pushes the rest off the page..deck-header, .deck-footer, .slide-number
and the progress bar are provided by assets/base.css + runtime.js.data-logo on <body> — don't paste
an <img> into every slide. See Custom logo below.<script src="../assets/runtime.js"></script>, so the deck supports
← → / T / A / F / S / O / hash deep-links.../ depth in asset paths. Every assets/ reference
is relative to the file that holds it: templates/deck.html uses
../assets/, templates/single-page/*.html use ../../assets/, and
templates/full-decks/*/index.html use ../../../assets/. Copying a file to
a new depth silently breaks all of them. Scaffold with
./scripts/new-deck.sh <name> [parent] [-t <template>], which computes the
prefix for wherever the deck lands and verifies every reference resolves..slide per logical page. runtime.js makes .slide.is-active
visible; all others are hidden.Five layouts in templates/single-page/ take real images. Pick by how many
images the page has to carry:
| I have… | Use | Why |
|---|---|---|
| one screenshot / diagram / chart | image-single.html | .img-frame.contain — letterboxed, never cropped |
| one photo that should carry the page | image-full-bleed.html | fills the slide, gradient scrim keeps the title readable |
| one image plus an argument | image-text-split.html | 50/50; add flip to .split to move the image right |
| 3–6 images | image-gallery.html | uniform grid; mixed source ratios are normalised by the frame |
| a before and an after | image-compare.html | both sides identical size, conclusion under each |
image-grid.html and image-hero.html are not in this list: they are
gradient-placeholder layouts with no <img> at all. Reach for them when you
want the shape of a bento wall without supplying pictures.
All five are built on one primitive from assets/base.css:
<figure class="img-frame"><img src="shot.png" alt=""></figure>
<figure class="img-frame contain" style="--img-ratio:4/3"><img src="diagram.svg" alt=""></figure>
.img-frame owns the aspect ratio and the crop; the <img> fills it with
object-fit: cover. That's what lets a user swap in a photo of any shape
without the layout breaking..img-frame.contain letterboxes instead of cropping — always use it for
screenshots, diagrams and logos.--img-ratio (default 16/10) and --img-pos (object-position) tune it..img-scrim / .img-cap / .img-tag are the scrim, caption and corner pill.index.html — keep them in the deck folder, e.g. examples/my-talk/shot.png.assets/demo-images/ holds the placeholder artwork used by these layouts:
hand-written SVG, ~1 KB each, no network needed.To brand a deck with a company / product logo, declare it once on <body>:
<body data-logo="logo.svg"
data-logo-position="bottom-right"
data-logo-size="40px">
| Attribute | Default | Notes |
|---|---|---|
data-logo | — | Image URL, relative to the deck's own HTML file. Required. |
data-logo-position | top-right | top-left / top-right / bottom-left / bottom-right |
data-logo-size | 44px | Any CSS length; sets the logo's height, width follows the aspect ratio |
data-logo-opacity | .9 | 1 for full strength |
data-logo-alt | "" | Alt text |
<section class="slide" data-no-logo> — usually
the cover and any full-bleed image slide that carries its own branding.--logo-inset-x / --logo-inset-y on .deck-logo.<div class="deck">
<img class="deck-logo" data-pos="bottom-left" src="logo.svg" alt="">
This path needs no JS at all — base.css styles both the same way.data-no-logo slides are skipped there too. Per-page printing is
painted by runtime.js + @media print; a deck that omits the runtime still
gets the logo on screen, but only on one page of a PDF.See references/authoring-guide.md for a step-by-step walkthrough: file structure, naming, how to transform an outline into a deck, how to choose layouts and themes per audience, how to do a Chinese + English deck, and how to export.
html-ppt/
├── SKILL.md (this file)
├── references/ (detailed catalogs, load as needed)
├── assets/
│ ├── base.css (tokens + primitives — do not edit per deck)
│ ├── demo-images/*.svg (tiny offline placeholders for the image-* layouts)
│ ├── fonts.css (webfont imports)
│ ├── runtime.js (keyboard + presenter + overview + theme cycle)
│ ├── themes/*.css (36 token overrides, one per theme)
│ └── animations/
│ ├── animations.css (27 named CSS entry animations)
│ ├── fx-runtime.js (auto-init [data-fx] on slide enter)
│ └── fx/*.js (20 canvas FX modules: particles/graph/fireworks…)
├── templates/
│ ├── deck.html (minimal 6-slide starter)
│ ├── theme-showcase.html (36 slides, iframe-isolated per theme)
│ ├── layout-showcase.html (iframe tour of all 36 layouts)
│ ├── animation-showcase.html (20 FX + 27 CSS animation slides)
│ ├── full-decks-index.html (gallery of all 15 full-deck templates)
│ ├── full-decks/<name>/ (15 scoped multi-slide deck templates)
│ └── single-page/*.html (36 layout files with demo data)
├── scripts/
│ ├── new-deck.sh (scaffold a deck from deck.html)
│ └── render.sh (headless Chrome → PNG)
└── examples/demo-deck/ (complete working deck)
scripts/render.sh wraps headless Chrome at
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome. For multi-slide
capture, runtime.js exposes #/N deep-links, and render.sh iterates 1..N.
./scripts/render.sh templates/single-page/kpi-grid.html # single page
./scripts/render.sh examples/demo-deck/index.html 8 out-dir # 8 slides, custom dir
← → Space PgUp PgDn Home End navigate
swipe left / right (touch) navigate — phones and tablets, no keyboard needed
F fullscreen
S open presenter window (magnetic cards: current/next/script/timer)
N quick notes drawer (bottom overlay)
R reset timer (in presenter window)
?preview=N URL param — force preview-only mode (single slide, no chrome)
O slide overview grid
T cycle themes (reads data-themes attr)
A cycle demo animation on current slide
#/N in URL deep-link to slide N
Esc close all overlays
MIT. Copyright (c) 2026 lewis <sudolewis@gmail.com>.
<div class="notes">…</div><div class="notes">, NOT as visible
<p> / <span> elements on the slide. The .notes class is display:none
by default — it only appears in the S overlay. Slides should contain ONLY
audience-facing content (titles, bullet points, data, charts, images).