Screenshot To Html logo

Screenshot To Html

Community
sevzq
screenshot-to-html

Replicate a UI screenshot/image/mockup into a high-fidelity, self-contained HTML page. Faithful image-to-HTML / screenshot-to-code cloning that matches the RENDERED result (not copied computed numbers) through a render -> screenshot -> compare -> refine loop using the local Chrome. Use whenever the user gives an image/screenshot/mockup/Figma export and wants HTML/CSS (plain or Tailwind), or asks to "复刻 / 还原 / clone / recreate / turn this design into a webpage".

Overview

Publishersevzq
Repositoryscreenshot-to-html
Skill namescreenshot-to-html
Stars
14
Forks
5
Bundled files
97
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 97 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by sevzq on GitHub. Read the source before you install it.

Installation

Install the Screenshot To Html AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/sevzq/screenshot-to-html/tree/main
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/sevzq/screenshot-to-html.git \
  .claude/skills/screenshot-to-html
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Screenshot To Html in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Screenshot To Html on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Screenshot To Html is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

screenshot-to-html — Screenshot to High-Fidelity HTML

Turn a UI image into a clean, self-contained HTML page whose rendered output matches the target image. Respond to the user in their language (they often write Chinese); keep chat replies short and let the work happen in files.

Core principle: replicate the RENDERED state, not the COMPUTED state

The target image is the ground truth of the final rendered pixels. Reproduce that, not a mechanical transcription of per-element values.

  • Computed-state cloning (do NOT do this). Eyedropper every hex, "measure" pixel coordinates/sizes, and paste getComputedStyle-style numbers into absolute-positioned divs. Result: magic-number soup, non-semantic, not responsive, brittle — and small extraction errors compound so it looks worse.
  • Rendered-state cloning (DO this). Read the design like a developer: infer semantic structure, a small set of design tokens (palette, type scale, spacing rhythm, radii, shadows), and layout intent (flex/grid). Build it, then render your code, screenshot it, and compare against the target, and iterate. Optimize "does my render look like the target," goal: render(code) ≈ target.

This is why the workflow is a feedback loop, not a one-shot dump.

Workflow

Copy this checklist and track progress:

- [ ] Phase 0 — Setup (inputs, stack, target width, deps, assets)
- [ ] Phase 1 — Read the design (global -> components -> exact text)
- [ ] Phase 2 — Build the first draft (semantic + tokens, self-contained)
- [ ] Phase 3 — Rendered-state loop (render, compare, fix; repeat 2-4x)
- [ ] Phase 4 — Interactivity & states (affordances + behavior, then verify)
- [ ] Phase 5 — Final checks
- [ ] Phase 6 — Enhance with motion (optional)

Phase 0 — Setup

  • Confirm inputs: the target image path(s) and the desired output file path.
  • Assets are automatic (no questions by default). Fill each slot with what gives the sharpest, most faithful result — not "crop everything": user-supplied assets win; real logos as inline SVG / official files; specific unique content cropped from the source (scripts/crop.mjs) when that region is sharp; generic photos from Unsplash / picsum; a https://placehold.co block as last resort. Quality gate: never ship a blurry upscaled crop — swap a soft crop for a sharp stock photo. Only ask once (non-blocking) if an asset is brand-critical AND no layer can approximate it. See Images & assets in reference.md.
  • Pick the stack (ask only if unclear): vanilla (HTML + plain CSS, self-contained, default) or tailwind (HTML + Tailwind CDN). See Stacks.
  • Understand the canvas & scale FIRST — before writing any CSS. Read the pixel size (sips -g pixelWidth -g pixelHeight <image>), then decide a design width in CSS px, not the raw pixel count:
    • Screenshots are usually retina (@2x/@3x), so the file is 2-3x the CSS width. Do not just divide and build at that size — that ships a shrunken page with ~10px nav text that looks tiny at 100% zoom. Map to a real breakpoint: web -> 1280 or 1440; mobile -> 375/390/393.
    • Build at that width with real-world type sizes (hero ~48-72px, body ~16-18px) and keep it responsive/fluid (clamp(), max-width, %), so it opens at a normal size and adapts — never a fixed miniature.
    • Run the render/compare loop at this design width; --scale 2 only sharpens the diff, it does not mean "author at half size."
  • Ensure render deps once (no browser download): npm i -D playwright-core.

Phase 1 — Read the design (global first, then local)

Look at the image carefully and write a short build spec. Global before local:

  • Layout: page max-width, column grid, section order, alignment.
  • Color tokens: name 4-8 colors (bg, surface, ink, muted, brand, accent, line). Account for gradients/overlays/opacity — never trust one pixel.
  • Type: families (serif vs sans, geometric vs humanist -> closest Google Font), the heading->body scale, weights, letter-spacing, line-height.
  • Spacing rhythm (base 4/8px), border-radii, shadow depth, borders/dividers.
  • Components: nav, hero, feature/bento, stats, cards, testimonials, CTA, footer — note structure and repetition (build one, loop the data).
  • Content: transcribe the exact visible text (do not invent or translate it).

Do NOT record pixel coordinates. Record relationships and tokens. For the full rubric see reference.md.

Phase 2 — Build the first draft

  • One self-contained file (inline <style>, minimal inline JS only if needed).
  • Semantic HTML (header/nav/main/section/article/footer, headings in order).
  • Put tokens in :root CSS variables; build layout with flex/grid, fluid sizing (clamp, min()), not fixed pixel frames.
  • Use the exact text from the image.
  • Images: fill each slot with the best layer for that slot (see Phase 0) — crop specific, unique content from the source when it's sharp (node scripts/crop.mjs --in <target> --rect x,y,w,h --out assets/<name>.png), use a sharp Unsplash/picsum photo for generic imagery (a fuzzy crop is worse than a real photo), else https://placehold.co/<w>x<h> with a <!-- asset: ... --> note. Icons: inline SVG (avoid emoji-as-icon).
  • Match the image's breakpoint first; add sensible responsive behavior without inventing layouts you cannot see.

Phase 3 — Rendered-state loop (the important part)

  1. Render your draft to a screenshot:
    bash
    node scripts/shot.mjs \
      --in <output.html> --out tmp/screenshot-to-html/v1.png --width <DESIGN_WIDTH>
  2. View both the target image and your render. Compare region by region and list concrete diffs, prioritized: layout/structure > sizing/spacing > color/contrast > typography > polish (shadows, radii, gradients).
  3. Fix the top issues with semantic edits (adjust tokens/layout, not magic numbers). Re-render to v2.png, v3.png, ...
  4. Repeat until differences are cosmetic (usually 2-4 rounds). Each round must reduce the visual gap; if a change makes it worse, revert it.

Comparison tips and common illusions are in reference.md.

Phase 4 — Interactivity & states (make it a page, not an image)

A screenshot is one frozen frame — it can't show hover, focus, or what's clickable. Matching it alone ships a "webpage that's secretly an image." Make the replica behave like a real page:

  • Real elements. Anything that looks clickable is a <button> or <a href> (or role="button" + tabindex="0"), never an inert <div>/<span>; inputs are real <input>.
  • Affordances by default (always). Every control gets cursor: pointer, a visible :hover change, a :focus-visible ring (keyboard), and an :active press, with a short transition (~120-180ms). These don't alter the resting look — they add feedback.
  • Functional behavior when the image implies it (minimal inline JS): tab/segmented controls switch the visible panel; a multi-screen mobile app navigates inside its device frame (bottom-nav / cards swap screens); modals/menus/dropdowns/accordions open and close (Esc / backdrop to dismiss); in-page nav smooth-scrolls. Don't invent flows you cannot infer.
  • A11y & motion. Logical heading order, alt text, visible focus, decent contrast; honor prefers-reduced-motion.
  • Verify, don't assume: node scripts/shot.mjs --in <file> --verify flags clickable-looking elements that are inert or missing a hover/focus state; --states captures hover/focus/open frames. Fix every dead control. Full detail in reference.md.
  • Tactile depth (zero-dependency). For the controls the screenshot implies — swipeable galleries, sliders, a heart that pops, drag-to-snap decks — make them feel hand-built with plain JS + CSS (pointer drag, velocity snap, press/scale). No motion library needed for any of it. Patterns and copy-paste snippets in references/interaction.md.

Phase 5 — Final checks

  • Side-by-side render vs target reads as "the same page."
  • Exact text; correct color/contrast; type scale and weights match.
  • Responsive sanity: render at a second width (e.g. --width 390) — nothing overlaps or overflows.
  • Interactivity: every clickable-looking element is real and shows hover/focus; --verify passes.
  • Self-contained and valid; no leftover probe/temp files (keep tmp/screenshot-to-html/ out of the deliverable). Report the final file path + final render.

Phase 6 — Enhance with motion (optional, only on request)

Interactivity (Phase 4) ships by default; GSAP motion/animation does not. Rich tactile feedback — drag, snap, like-pop — needs no library (references/interaction.md); GSAP is only for heavier, explicitly-requested choreography. Do not add motion on your own, and never ask about it — only enhance when the user explicitly requests animation ("加动效", "make it animated"). Then add restrained GSAP animation — high-impact moments, not AI-slop everywhere. Read references/animation.md for the patterns (load-in stagger, scroll-triggered reveal, hover micro-interactions), CDN setup, and pitfalls. Keep the HTML self-contained (GSAP via CDN) and honor prefers-reduced-motion; verify a settled frame with node scripts/shot.mjs --motion. This skill is self-contained; for deeper choreography you may optionally also install the official GSAP skills (npx skills add github.com/greensock/gsap-skills) — not required.

Scripts (paths relative to this skill directory)

scripts/shot.mjs — render a local HTML file with installed Google Chrome via playwright-core (no browser download); the render step of the loop.

bash
# full-page (default), crisp 2x:
node scripts/shot.mjs --in replica.html --out tmp/screenshot-to-html/v1.png --width 1280
# exact-pixel overlay: add --scale 1 ; above-the-fold only: --viewport-only ; keep motion: --motion

If Chrome is missing it falls back to bundled chromium (npx playwright install chromium).

scripts/crop.mjs — crop a rectangle out of the source screenshot to reuse real imagery (asset layer 2). Uses sharp if installed, else macOS sips.

bash
node scripts/crop.mjs --in <target.png> --rect x,y,w,h --out assets/hero.png

Stacks

Pick per request; both produce a single self-contained file.

vanilla (default) — HTML + plain CSS in one file. Tokens in :root. Best for matching a bespoke visual identity and staying dependency-free.

tailwind — add <script src="https://cdn.tailwindcss.com"></script> and build with utilities; map the palette/scale via the tailwind.config inline object.

Both stacks:

  • Fonts: Google Fonts <link> (pick the closest match to the image).
  • Icons: inline SVG, or Font Awesome https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css.
  • Missing images: layered fallback (crop from source -> Unsplash/picsum -> placehold.co).

Output & temp conventions

  • Final HTML: the path the user asks for. Default index.html; if a file already exists there and is unrelated, do not overwrite it — confirm or write to replica.html.
  • Screenshots/intermediates: tmp/screenshot-to-html/ (safe to delete). Create it if missing.

Quality expectations

  • Semantic, readable, maintainable; design tokens over magic numbers.
  • No absolute-position-everything layouts; no "measured" pixel coordinates.
  • Fidelity to the image: layout, exact text, color, type, spacing, radii, shadows.
  • Multiple screenshots = multiple pages/tabs: link or scaffold them sensibly.

Additional resources

  • reference.md — analysis rubric, comparison methodology, computed-state traps, fonts/colors/assets, the four-layer asset strategy.
  • references/interaction.md — zero-dependency tactile-polish standard (Phase 4): pointer-drag primitive, swipe/carousel snap, like-pop, toggles, reduced-motion.
  • references/animation.md — optional GSAP motion patterns (Phase 6): CDN setup, load-in/scroll/hover recipes, reduced-motion, pitfalls.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

and 37 more files.

Frequently asked questions

What does the Screenshot To Html AI skill do?

Replicate a UI screenshot/image/mockup into a high-fidelity, self-contained HTML page. Faithful image-to-HTML / screenshot-to-code cloning that matches the RENDERED result (not copied computed numbers) through a render -> screenshot -> compare -> refine loop using the local Chrome. Use whenever the user gives an image/screenshot/mockup/Figma export and wants HTML/CSS (plain or Tailwind), or asks to "复刻 / 还原 / clone / recreate / turn this design into a webpage".

Why use Screenshot To Html on TypingMind?

Because you install it once and use it with any model. Screenshot To Html is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Screenshot To Html in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/sevzq/screenshot-to-html/tree/main. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Screenshot To Html?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Screenshot To Html?

As many as you like. As long as a model supports skills, you can use Screenshot To Html with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Screenshot To Html AI skill free?

Yes. It is published on GitHub by sevzq under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇