stitch-html-components について
Stitch の画面、ローカル HTML、URL を、フレームワークやビルド工程なしでセマンティックな HTML5 と CSS に変換するスキルです。プラットフォーム非依存のページ、静的サイト、モバイル WebView を対象に、モバイルファーストのスタイルと最小限の JavaScript を用います。
主な機能
- 01HTML ソースをセマンティックな HTML5 と CSS に変換
- 02Stitch、ローカルファイル、URL に対応
- 03ライト・ダーク用 CSS トークンを生成
- 04モバイルファーストのレスポンシブスタイル
- 05JavaScript を基本的な操作に限定
活用シーン
- 01フレームワーク不使用の静的ページを作成
- 02モバイル WebView 用の HTML を準備
- 03フレームワーク選定前にプロトタイプを作成
MCP 対応
Stitch のソースでは、Stitch MCP ツールでツールの名前空間を調べ、画面メタデータを取得してから HTML をダウンロードします。ローカルファイルと URL の処理には Stitch MCP は不要です。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ gabelul/ stitch-kit --skill stitch-html-componentsインストール後、Claude Code で/stitch-html-componentsを入力して読み込まれたか確認します。
同梱ファイルresources/architecture-checklist.mdscripts/fetch-stitch.sh
詳細
Stitch → HTML5 + CSS(プラットフォーム非依存)
クリーンで依存関係のない HTML と CSS を専門とするフロントエンドエンジニアです。HTML ソース(Stitch の画面、ローカルファイル、URL)を、CSS カスタムプロパティを使ったセマンティックな HTML5 に変換します。React も Svelte もビルド手順も使いません。出力はデスクトップブラウザー、モバイルブラウザー、iOS WebView、Android WebView、Capacitor アプリ、Ionic シェルなど、どこでも動作します。
このスキルを使う場面
次のような場合にこのスキルを使います。
- ユーザーがプラットフォーム非依存の出力を求めている場合(「HTML だけ」「フレームワークなし」「どこでも動く」など)
- モバイルアプリの WebView(Capacitor、Ionic、Cordova)が対象の場合
- 静的サイトを構築する場合や、CMS に埋め込む場合
- ユーザーがまだフレームワークを選んでおらず、動作するプロトタイプを求めている場合
- Capacitor でネイティブモバイルアプリにラップする前に、HTML のベースを生成する場合
前提条件
HTML ソースが必要です。次のいずれかを利用できます。
- Stitch の画面 — Stitch MCP へのアクセスと、生成済みの画面が必要です
- ローカル HTML ファイル — Stitch アカウントは不要です
- URL — Stitch アカウントは不要です
手順 1:ソースを解決する
以降のすべての処理は、1 つのファイル temp/source.html を読み込みます。ユーザーから提供された内容に合った方法で HTML をそこに配置し、手順 2 に進みます。マークアップの取得元にかかわらず、このスキルの残りの手順は同じです。
Stitch の画面から取得する場合:
- ネームスペースの確認 —
list_toolsで Stitch MCP のプレフィックスを特定します - メタデータの取得 —
[prefix]:get_screenでデザイン JSON を取得します - HTML のダウンロード — GCS の URL には、信頼性の高いダウンローダーが必要です。
bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" - ビジュアル監査 — 書き換える前に
screenshot.downloadUrlを確認します。完全な解像度で取得するには URL に=s0を追加します。何も追加しない URL では、API が報告するwidth/heightに関係なく、512px のサムネイルが返されます。
ローカル HTML ファイルから取得する場合:
mkdir -p temp && cp "path/to/design.html" temp/source.html
URL から取得する場合:
bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
名前にかかわらず、このスクリプトは汎用の堅牢なダウンローダーです。リダイレクトを追跡し、一時的な失敗時には再試行し、gzip を処理し、結果が空の場合はエラーを明確に報告します。URL が Stitch を指しているかどうかは問いません。
**スクリーンショットから取得する場合:**アップロードする方法はありません。Stitch MCP API には画像アップロードツールがありません。テキストプロンプトから stitch-mcp-generate-screen-from-text でデザインを再現するか、HTML を手書きして上記のローカルファイルの方法を使ってください。
API キーが必要なのは Stitch の方法だけです。ローカルファイルや URL の変換には、Google アカウントは一切必要ありません。
手順 2:ファイル構成
output/
├── index.html ← Main page (or rename per screen)
├── css/
│ ├── tokens.css ← CSS custom properties (light + dark)
│ ├── base.css ← Reset, body defaults, typography
│ └── components.css ← Component styles
├── js/
│ └── main.js ← Minimal JS (theme toggle, mobile menu only)
└── assets/
└── images/
複数画面のプロジェクトでは、画面ごとに HTML ファイルを用意します。共有 CSS は tokens.css と base.css に配置します。
手順 3:CSS カスタムプロパティ
ソースの色をセマンティックトークンに割り当てます。ライトモードとダークモードの両方を、必ず同時に生成します。次の順序で 16 進値を解決します。
<head>内のインラインtailwind.config(Stitch が出力するもの)— 存在する場合はそのまま使います。- ソース内にすでにある CSS カスタムプロパティ(
:root { --color-primary: ... })— 手書きやテンプレートを使った HTML で一般的です。 - リンクされたスタイルシートまたはインラインスタイルシート — 宣言された色、フォントファミリー、角丸、余白を解析します。
- 最終手段 — マークアップ内で最も頻繁に使われる計算済みの値(背景の主要色、文字色、アクセントカラー、見出し/本文のフォント、角丸)からトークンを導出し、推測した内容をユーザーに伝えて修正できるようにします。
URL を使う方法では HTML のレスポンスのみをダウンロードするため、外部リンクされたスタイルシートは含まれないことがあります。上記の方法でトークンを解決できない場合は、パレットを勝手に作らず、その旨を伝えてください。
/* css/tokens.css */
:root {
--color-background: [hex];
--color-surface: [hex];
--color-primary: [hex];
--color-primary-fg: [hex];
--color-text: [hex];
--color-text-muted: [hex];
--color-border: [hex];
--font-sans: [font-stack];
--font-mono: ui-monospace, monospace;
--radius-sm: [value];
--radius-md: [value];
--radius-lg: [value];
--shadow-sm: 0 1px 3px rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 12px rgb(0 0 0 / 0.1);
--transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Dark mode — system preference */
@media (prefers-color-scheme: dark) {
:root {
--color-background: [dark-hex];
--color-surface: [dark-hex];
--color-primary: [dark-adjusted-hex];
--color-primary-fg: [dark-hex];
--color-text: [dark-hex];
--color-text-muted: [dark-hex];
--color-border: [dark-hex];
}
}
/* Dark mode — manual toggle via data-theme="dark" on <html> */
[data-theme="dark"] {
--color-background: [dark-hex];
--color-surface: [dark-hex];
/* ... same values as above */
}
プロジェクトにすでに design-tokens.css(stitch-design-system で作成)がある場合は、トークンを再作成せず、それをインポートしてください。
手順 4:ベース CSS
/* css/base.css */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
font-size: 16px;
/* Safe area insets for notched phones */
padding: env(safe-area-inset-top) env(safe-area-inset-right)
env(safe-area-inset-bottom) env(safe-area-inset-left);
-webkit-text-size-adjust: 100%; /* Prevent font scaling on iOS rotation */
}
body {
font-family: var(--font-sans);
background-color: var(--color-background);
color: var(--color-text);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
/* Skip link for accessibility */
.sr-only {
position: absolute; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden;
clip: rect(0,0,0,0); white-space: nowrap; border-width: 0;
}
.skip-link { /* ... see stitch-a11y skill */ }
/* Focus ring — keyboard only */
*:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
border-radius: 2px;
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
ステップ 5:セマンティックな HTML 構造
Stitch のレイアウトをセマンティックな HTML5 に変換します。セマンティック要素が適切な箇所で、<div> は使用しないでください。
| Stitch 要素 | → HTML 要素 |
|---|---|
| ページシェル/アプリのクローム | <body> → <header> + <main> + <footer> |
| ナビゲーションバー | <nav aria-label="Main navigation"> |
| メインコンテンツ領域 | <main id="main-content"> |
| 記事/投稿/カードのコンテンツ | <article> |
| サイドバー | <aside> |
| ページのセクション | <section aria-labelledby="section-id"> |
| ボタン(href なし) | <button type="button"> |
| ナビゲーションリンク | <a href="..."> |
| フォームコンテナー | すべての入力に対する <label> を含む <form> |
| 画像 | <img alt="descriptive text"> |
モバイル HTML テンプレート:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="[--color-background hex]">
<title>[Screen title]</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="css/tokens.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/components.css">
</head>
<body>
<a href="#main-content" class="skip-link">Skip to content</a>
<div class="app-shell">
<header class="app-header" role="banner">
<nav aria-label="Main navigation">
</nav>
</header>
<main id="main-content" class="app-main">
</main>
<nav class="bottom-nav" aria-label="Tab navigation">
</nav>
</div>
<script src="js/main.js" type="module"></script>
</body>
</html>
ステップ 6:モバイルファーストの CSS ルール
すべてのコンポーネントで、次のモバイル要件を満たしてください。
タッチターゲット
/* All interactive elements: minimum 44×44px tap area */
button, a, [role="button"] {
min-height: 44px;
min-width: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
}
スクロール
/* Smooth scroll on iOS */
.scrollable {
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain; /* Prevent scroll chaining */
}
ボトムナビゲーションバー
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
/* Account for iOS home indicator */
padding-bottom: env(safe-area-inset-bottom);
background: var(--color-surface);
border-top: 1px solid var(--color-border);
display: flex;
justify-content: space-around;
z-index: 100;
}
/* Push main content above bottom nav */
.app-main {
padding-bottom: calc(60px + env(safe-area-inset-bottom));
}
レスポンシブブレークポイント
/* Mobile-first: base styles are for mobile */
/* Tablet (768px+) */
@media (min-width: 768px) {
.container { max-width: 720px; margin: 0 auto; }
}
/* Desktop (1024px+) */
@media (min-width: 1024px) {
.container { max-width: 1200px; }
.bottom-nav { display: none; } /* Hide bottom nav, use sidebar */
.sidebar { display: block; } /* Show desktop sidebar */
}
ステップ 7:最小限の JavaScript
JS は必要最小限に抑えてください。JS が必要なのは次の機能だけです。
- テーマの切り替え(ダーク/ライト)
- モバイルメニューの開閉
- アコーディオン/タブのインタラクティブな動作
// js/main.js
// Dark mode toggle
const html = document.documentElement;
const savedTheme = localStorage.getItem('theme') || 'light';
html.setAttribute('data-theme', savedTheme);
document.getElementById('theme-toggle')?.addEventListener('click', () => {
const next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});
// Mobile menu toggle
document.getElementById('menu-toggle')?.addEventListener('click', () => {
const nav = document.getElementById('mobile-nav');
const expanded = nav.getAttribute('aria-expanded') === 'true';
nav.setAttribute('aria-expanded', String(!expanded));
nav.classList.toggle('is-open');
});
ステップ 8:Capacitor/WebView に関する注意事項
この HTML を Capacitor または Ionic アプリに埋め込む場合:
- すべてのアセットパスは相対パスにしてください(先頭に
/を付けない):./css/tokens.css、./assets/logo.png - Capacitor は
www/またはdist/ディレクトリを読み込むため、そこに出力してください - Capacitor の
capacitor.config.jsonで WebDir を設定します:"webDir": "www" - ネイティブ API(カメラ、ファイルシステム)を呼び出すには、Capacitor プラグインの JS API を使用します。このスキルの対象範囲外です
トラブルシューティング
| 問題 | 対処法 |
|---|---|
| iOS の画面回転時にフォントが拡大表示される | html に -webkit-text-size-adjust: 100% を追加します |
| ノッチの下にコンテンツが隠れる | env(safe-area-inset-*) のパディングを追加します |
| iOS でスクロールが遅く感じられる | -webkit-overflow-scrolling: touch を追加します |
| ボトムナビがコンテンツに重なる | ナビの高さとセーフエリアを足した値を <main> の padding-bottom に設定します |
| モバイルでクリックが遅延する(300ms) | ボタンに touch-action: manipulation を追加します |
統合
- 最初に
stitch-design-systemを実行してdesign-tokens.cssを生成し、トークンを再作成する代わりにそれをインポートします - アクセシビリティの確認として、次に
stitch-a11yを実行します - CSS のみのトランジションを追加するには
stitch-animateを実行します(ほとんどのアニメーションで JS は不要です)
参考資料
resources/mobile-template.html— モバイル HTML の完全なボイラープレートresources/architecture-checklist.md— リリース前チェックリストscripts/fetch-stitch.sh— GCS HTML を確実にダウンロードするスクリプト