screenshot-to-html について
screenshot-to-htmlは、UIスクリーンショットを自己完結型のHTMLページに再現するスキルです。セマンティックな構成やデザイントークンを推定し、レンダリング結果を比較しながら精度を高める手順を示します。
主な機能
- 01スクリーンショットからHTMLを作成
- 02セマンティックHTMLとデザイントークン
- 03レンダリング比較の反復
- 04レスポンシブレイアウトの指針
- 05操作状態とアクセシビリティ
- 06任意のモーション指針
活用シーン
- 01スクリーンショットからWebページを再現
- 02視覚比較によるレイアウト調整
- 03再現ページへの操作可能なコントロール追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sevzq/ screenshot-to-html --skill screenshot-to-htmlインストール後、Claude Code で/screenshot-to-htmlを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreREADME.zh-CN.mdREADME.mdLICENSE.nojekyllAGENTS.mdpackage-lock.jsonpackage.jsonindex.htmlreference.mdexamples/app-elevenlabs/output.htmlexamples/app-spotify/output.htmlexamples/dashboard-stripe/output.htmlexamples/landing-clay/output.htmlexamples/landing-cloudflare/output.htmlexamples/landing-linear/output.htmlexamples/landing-modal/output.htmlexamples/landing-stripe/output.htmlexamples/mobile-airbnb/output.htmlexamples/mobile-tesla/output.htmlreferences/animation.mdinteraction.mdscripts/crop.mjsshot.mjs詳細
screenshot-to-html — スクリーンショットから高忠実度の HTML を作成
UI 画像を、レンダリング結果が対象画像と一致する、クリーンで自己完結型の HTML ページに変換します。ユーザーにはその言語で応答してください(中国語で書くことがよくあります)。チャットでの返信は短くし、作業はファイル内で進めてください。
基本原則:計算値ではなく、レンダリングされた状態を再現する
対象画像は、最終的なレンダリング済みピクセルの基準です。要素ごとの値を機械的に書き写すのではなく、対象画像を再現してください。
- 計算値のクローン(これはしないでください)。 すべての色をスポイトで拾い、ピクセル座標やサイズを「測定」して、
getComputedStyleのような数値を絶対配置の div に貼り付けます。その結果、マジックナンバーだらけで、セマンティックではなく、レスポンシブにもならず、脆弱になります。さらに、小さな抽出誤差が重なり、見た目はかえって悪くなります。 - レンダリング状態のクローン(こちらを行ってください)。 開発者としてデザインを読み解き、セマンティックな構造、少数のデザイントークン(配色、文字サイズのスケール、余白のリズム、角丸、影)、レイアウトの意図(flex/grid)を推測します。実装したら、コードをレンダリングしてスクリーンショットを撮り、対象画像と比較しながら調整します。「自分のレンダリングが対象画像に似ているか」を最適化し、目標は
render(code) ≈ targetです。
そのため、このワークフローは一度きりの書き出しではなく、フィードバックループになっています。
ワークフロー
このチェックリストをコピーして、進捗を記録してください。
- [ ] 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)
フェーズ 0 — セットアップ
- 入力を確認します。対象画像のパスと、出力ファイルのパスを確認してください。
- アセットは自動で用意します(通常、質問は不要です)。 「すべてを切り抜く」のではなく、最も鮮明で忠実な結果になるものを各枠に使用します。ユーザー提供のアセットを優先し、実際のロゴにはインライン SVG または公式ファイルを使います。鮮明な場合は、ソース内の固有のコンテンツを切り抜きます(
scripts/crop.mjs)。一般的な写真には Unsplash /picsumを使い、最後の手段としてhttps://placehold.coのブロックを使います。品質基準として、ぼやけた画像を拡大した切り抜きは決して納品しないでください。ぼやけた切り抜きは、鮮明なストックフォトに差し替えます。アセットがブランドに不可欠で、どのレイヤーでも近似できない場合に限り、一度だけ(作業を止めずに)確認してください。詳しくは reference.md の画像とアセットを参照してください。 - スタックを選びます(不明な場合のみ確認してください)。
vanilla(HTML + 通常の CSS。自己完結型で、デフォルト)またはtailwind(HTML + Tailwind CDN)を選択します。スタックを参照してください。 - CSS を書く前に、まずキャンバスとスケールを把握します。 ピクセルサイズ(
sips -g pixelWidth -g pixelHeight <image>)を確認してから、元のピクセル数ではなく、CSS px でのデザイン幅を決めます。- スクリーンショットは通常 Retina(
@2x/@3x)のため、ファイルの幅は CSS 幅の 2~3 倍です。単純に割ってそのサイズで作らないでください。100% 表示でナビゲーションの文字が~10pxと小さく見える、縮小されたページになってしまいます。実際のブレークポイントに合わせてください。ウェブなら1280または1440、モバイルなら375/390/393です。 - その幅を基準に、実世界で一般的な文字サイズ(ヒーローは約 48~72px、本文は約 16~18px)で作り、レスポンシブで流動的になるようにします(
clamp()、max-width、%)。通常のサイズで表示され、サイズに応じて調整されるようにし、固定サイズの縮小版にはしないでください。 - このデザイン幅でレンダリングと比較を繰り返します。
--scale 2は差分を鮮明にするだけであり、「半分のサイズで実装する」という意味ではありません。
- スクリーンショットは通常 Retina(
- レンダリングに必要な依存関係を一度だけインストールします(ブラウザーのダウンロードは不要です)。
npm i -D playwright-coreを実行してください。
フェーズ 1 — デザインを読み取る(まず全体、次に細部)
画像を注意深く確認し、簡潔な実装仕様を書きます。細部より先に全体を把握します。
- レイアウト:ページの最大幅、カラムグリッド、セクションの順序、配置。
- カラートークン:4〜8色(背景、サーフェス、文字、控えめな文字、ブランド、アクセント、線)の名前を挙げます。 グラデーション/オーバーレイ/不透明度も考慮します。1ピクセルだけを見て判断しないでください。
- タイポグラフィ:フォントファミリー(セリフ体かサンセリフ体か、幾何学的かヒューマニスト系か → 最も近い Google Font)、 見出しから本文までのサイズの段階、ウェイト、文字間隔、行の高さ。
- 余白のリズム(基本単位は 4/8px)、角丸、影の深さ、枠線/区切り線。
- コンポーネント:ナビゲーション、ヒーロー、特徴/ベントー、統計、カード、お客様の声、CTA、フッター — 構造と繰り返しのパターンを記録します(1つ作成し、データをループ処理します)。
- コンテンツ:画像に表示されているテキストを正確に書き起こします(創作や翻訳はしません)。
ピクセル座標は記録しないでください。位置関係とトークンを記録します。 評価基準の全文は reference.md を参照してください。
フェーズ 2 — 初稿を作成する
- 自己完結型のファイルを1つ用意します(
<style>をインラインで記述し、必要な場合のみ最小限のインライン JS を使用)。 - セマンティック HTML(
header/nav/main/section/article/footer、見出しは順序どおり)。 - トークンは
:rootの CSS 変数に定義し、レイアウトにはflex/gridと流動的なサイズ指定(clamp、min())を使用します。固定ピクセルのフレームは使いません。 - 画像のテキストを正確に使用します。
- 画像:各スロットに最適なレイヤーを配置します(フェーズ 0 を参照)。元画像のシャープな箇所から、スロットに合った固有のコンテンツを切り抜きます(
node scripts/crop.mjs --in <target> --rect x,y,w,h --out assets/<name>.png)。汎用的な画像には、鮮明な Unsplash/picsumの写真を使用します(ぼやけた切り抜きより実際の写真のほうが適しています)。それ以外の場合はhttps://placehold.co/<w>x<h>を使い、``メモを添えます。アイコンにはインライン SVG を使用します(絵文字をアイコンとして使わないでください)。 - まず画像のブレークポイントに合わせます。その後、見えないレイアウトを創作せず、適切なレスポンシブ動作を追加します。
フェーズ 3 — レンダリング結果を見ながら調整する(最重要)
- 初稿をスクリーンショットにレンダリングします。
node scripts/shot.mjs \ --in <output.html> --out tmp/screenshot-to-html/v1.png --width <DESIGN_WIDTH> - 目標画像とレンダリング結果の両方を確認します。領域ごとに比較し、具体的な差分を優先度順に列挙します。優先順位は、レイアウト/構造 > サイズ/余白 > 色/コントラスト > タイポグラフィ > 仕上げ(影、角丸、グラデーション)です。
- 意味のある編集で優先度の高い問題を修正します(場当たり的な数値ではなく、トークン/レイアウトを調整します)。
v2.png、v3.png、…として再レンダリングします。 - 差分が見た目の細部だけになるまで繰り返します(通常 2〜4 回)。各ラウンドで見た目の差が縮まるようにします。変更によって悪化した場合は元に戻します。
比較のヒントとよくある錯覚については reference.md を参照してください。
フェーズ 4 — インタラクティブ性と状態(画像ではなくページにする)
スクリーンショットは静止した一場面にすぎず、ホバーやフォーカス、クリック可能な要素は表現できません。見た目だけを再現すると、「実は画像でできたウェブページ」を作ることになります。レプリカを実際のページのように動作させましょう。
- 実際の要素を使います。 クリックできそうに見えるものはすべて、
<button>または<a href>(あるいはrole="button"+tabindex="0")にします。機能しない<div>/<span>は使いません。入力欄には実際の<input>を使います。 - 操作可能であることを常に示します。 すべてのコントロールに
cursor: pointer、目に見える:hoverの変化、(キーボード操作用の):focus-visibleリング、押したときの:active表示を設定し、短いtransition(約120~180ms)を付けます。これらは通常時の見た目を変えず、操作への反応を加えます。 - 画像から読み取れる動作を実装します(最小限のインライン JS を使用)。タブ/セグメントコントロールでは表示パネルを切り替えます。複数画面のモバイルアプリでは、デバイス枠内で画面を移動できるようにします(ボトムナビゲーション/カードで画面を切り替えます)。モーダル/メニュー/ドロップダウン/アコーディオンは開閉できるようにします(Esc/背景のクリックで閉じます)。ページ内ナビゲーションではスムーズスクロールを使います。推測できないフローは作りません。
- アクセシビリティと動き。 見出しの順序を適切にし、
altテキストと明瞭なフォーカス表示を用意し、十分なコントラストを確保します。prefers-reduced-motionに対応します。 - 思い込みではなく、検証します。
node scripts/shot.mjs --in <file> --verifyを実行すると、クリックできそうに見えるのに機能しない要素や、ホバー/フォーカス状態がない要素を検出します。--statesではホバー/フォーカス/開いた状態のフレームを取得します。動作しないコントロールはすべて修正してください。詳しくは reference.md をご覧ください。 - 触り心地のある奥行き(依存関係ゼロ)。 スクリーンショットから想定されるコントロール(スワイプ可能なギャラリー、スライダー、弾むハート、ドラッグしてスナップするカードデッキなど)には、素の JS と CSS で手作りのような操作感を加えます(ポインタードラッグ、速度に応じたスナップ、押したときの拡大・縮小)。どれもモーションライブラリは不要です。パターンとコピー&ペースト用のスニペットは references/interaction.md にあります。
フェーズ 5 — 最終チェック
- 横に並べて表示した際、レンダリング結果とターゲットが「同じページ」に見えること。
- テキストが完全に一致し、色/コントラスト、文字サイズとウェイトが合っていること。
- レスポンシブ表示を確認します。別の幅(例:
--width 390)でもレンダリングし、重なりやはみ出しがないこと。 - インタラクティブ性: クリックできそうに見える要素がすべて実際に機能し、ホバー/フォーカス表示があること。
--verifyが通ること。 - 自己完結していて有効であること。調査用/一時ファイルが残っていないこと(
tmp/screenshot-to-html/は成果物に含めないでください)。最終ファイルのパスと最終レンダリングを報告します。
フェーズ 6 — 動きを加える(任意。依頼された場合のみ)
インタラクティブ性(フェーズ 4)は標準で実装しますが、GSAP による動き/アニメーションは標準では実装しません。 ドラッグ、スナップ、いいね時のポップなど、豊かな触り心地のフィードバックにライブラリは不要です(references/interaction.md)。GSAP は、明示的に依頼された大がかりな演出に限って使用します。独断で動きを追加したり、希望を尋ねたりしてはいけません。「加动效」「make it animated」など、ユーザーからアニメーションを明示的に依頼された場合にのみ追加します。その場合は、控えめな GSAP アニメーションを追加します。あらゆる場所を AI っぽい演出で埋めるのではなく、効果の大きい場面に絞ります。パターン(読み込み時の段階表示、スクロール連動の表示、ホバー時のマイクロインタラクション)、CDN の設定、注意点については references/animation.md をご覧ください。HTML は自己完結させ(GSAP は CDN 経由)、prefers-reduced-motion に対応します。node scripts/shot.mjs --motion で、動きが落ち着いた状態のフレームを検証します。
このスキルは自己完結しています。より複雑な演出には、必要に応じて公式 GSAP スキル(npx skills add github.com/greensock/gsap-skills)もインストールできますが、必須ではありません。
スクリプト(パスはこのスキルのディレクトリからの相対パス)
scripts/shot.mjs — playwright-core を介して、インストール済みの Google Chrome でローカル HTML ファイルをレンダリングします(ブラウザーのダウンロードは不要)。一連の作業におけるレンダリング手順です。
# 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
Chrome が見つからない場合は、同梱の chromium にフォールバックします(npx playwright install chromium)。
scripts/crop.mjs — 元のスクリーンショットから範囲を切り抜き、実際の画像素材として再利用します(アセットレイヤー 2)。sharp がインストールされていれば使用し、そうでなければ macOS の sips を使用します。
node scripts/crop.mjs --in <target.png> --rect x,y,w,h --out assets/hero.png
スタック
リクエストに応じて選択してください。どちらも単一の自己完結型ファイルを生成します。
vanilla(デフォルト)— HTML とプレーン CSS を1つのファイルにまとめます。トークンは :root に定義します。独自のビジュアルアイデンティティを再現し、依存関係をなくすのに最適です。
tailwind — <script src="https://cdn.tailwindcss.com"></script> を追加し、ユーティリティを使って構築します。tailwind.config のインラインオブジェクトでパレットとスケールを指定します。
どちらのスタックでも:
- フォント:Google Fonts の
<link>を使用します(画像に最も近いものを選びます)。 - アイコン:インライン SVG、または Font Awesome
https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.cssを使用します。 - 画像がない場合:段階的な代替手段を使います(ソースから切り抜く → Unsplash/picsum →
placehold.co)。
出力と一時ファイルの規則
- 最終 HTML:ユーザーが指定したパスに保存します。デフォルトは
index.htmlです。その場所に無関係なファイルがすでに存在する場合、上書きしないでください。確認するか、replica.htmlに書き込んでください。 - スクリーンショット/中間ファイル:
tmp/screenshot-to-html/(安全に削除できます)。存在しない場合は作成してください。
品質要件
- セマンティックで読みやすく、保守しやすいコードにします。マジックナンバーではなくデザイントークンを使います。
- 何もかも絶対位置で配置するレイアウトや、「測定した」ピクセル座標は使いません。
- 画像への忠実度:レイアウト、正確なテキスト、色、書体、余白、角丸、シャドウ。
- スクリーンショットが複数ある場合は、複数のページ/タブとして、適切にリンクまたは構成します。
追加リソース
- reference.md — 分析の評価基準、比較方法、計算後の状態に関する落とし穴、フォント/色/アセット、4層のアセット戦略。
- references/interaction.md — 依存関係なしで触感のある仕上がりを実現する標準(フェーズ4):ポインターによるドラッグの基本処理、スワイプ/カルーセルのスナップ、いいね時のポップ、切り替え、モーション低減。
- references/animation.md — 任意の GSAP モーションパターン(フェーズ6):CDN の設定、読み込み時/スクロール/ホバーのレシピ、モーション低減、注意点。