Claude Codeでレスポンシブデザインを実装する実務ガイド
Claude Codeでレスポンシブデザインを実装。mobile-first CSS、clamp、画像、ナビ、Playwright検証まで解説。
Claude Codeに任せる前に決めること
レスポンシブデザインは「スマホでも見えるようにする作業」ではありません。画面幅、入力方法、通信環境、画像の重さ、広告やCTAの位置、テーブルの読みやすさまで含めて、読者が迷わず目的を達成できる状態を作る設計です。Claude Codeに「モバイル対応して」とだけ頼むと、見た目は整っても、横スクロール、固定幅カード、巨大画像、スマホで潰れるナビが残りがちです。
この記事では、Claude Codeを使ってレスポンシブデザインを実装する実務手順を、初心者でも追える形でまとめます。mobile-first CSSは「小さい画面を基本にして、大きい画面だけ足す」考え方です。clamp()は最小値、理想値、最大値を一行で指定するCSS関数です。コンテナクエリは、画面全体ではなく親要素の幅に応じて部品を変えるCSSです。最初にこの言葉を短く伝えるだけで、Claude Codeの提案はかなり現実寄りになります。
公式情報としては、MDNのResponsive design、@container、clamp()、responsive imagesを基準にします。検証はPlaywrightのScreenshotsとVisual comparisonsを使います。Claude Code自体は公式のClaude Code overviewとHow Claude Code worksにある通り、コードベースを読み、編集し、コマンドで検証する道具として扱うのが安全です。
関連する設計の土台はClaude Codeでデザインシステムを構築する、見落としやすい操作性はClaude Codeでアクセシビリティ対応を効率化する方法、ブラウザ検証の詳しい流れはClaude CodeでPlaywrightテストを自動化する方法も合わせて読むとつながります。
実装の全体像
レスポンシブ対応は、CSSを最後に足す作業にすると失敗します。Claude Codeには「既存画面を読んで、部品ごとに壊れる幅を見つけ、CSSと画像と検証を一緒に更新する」と依頼します。
flowchart LR
A["既存画面を読む"] --> B["mobile-firstの基礎CSS"]
B --> C["fluid gridとclamp()"]
C --> D["container queryで部品単位に調整"]
D --> E["画像と表のモバイル対応"]
E --> F["Playwrightでスクリーンショット検証"]
最初の依頼文は次のくらい具体的で十分です。ポイントは、見た目の希望だけでなく、守るべき導線、触ってよいファイル、検証方法まで渡すことです。
既存の /responsive-demo ページをレスポンシブ化してください。
前提:
- mobile-first CSSにする
- 320px, 390px, 768px, 1024px, 1440pxで横スクロールを出さない
- ナビ、カード、価格表、記事CTAが重ならないようにする
- 画像は width/height, srcset, sizes, loading を設定する
- CSS Grid, clamp(), @container を優先し、不要なJSで幅判定しない
- 変更後に Playwright でスクリーンショットと overflow を確認する
禁止:
- 既存のURL、CTAリンク、アクセシブルな見出し階層を壊さない
- ピクセル固定の巨大な min-width を増やさない
このように書くと、Claude Codeは「見た目を整える」だけでなく、変更範囲と完了条件を理解できます。初心者ほど、ここを省略せずに書いた方が差分をレビューしやすくなります。
コピーして動かせるHTML
まずは、ナビ、ヒーロー、カード、比較表を含む小さなページを用意します。画像パスだけ自分のプロジェクトに合わせれば、そのまま静的HTMLとして開けます。実アプリではReactやAstroに分けても構いませんが、最初はHTMLとCSSだけで崩れ方を確認する方が学びやすいです。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Responsive Demo</title>
<link rel="stylesheet" href="./responsive-demo.css" />
</head>
<body>
<header class="site-nav">
<a class="brand" href="/">ClaudeCodeLab</a>
<nav class="nav-links" aria-label="メインナビゲーション">
<a href="/blog/">記事</a>
<a href="/products/">教材</a>
<a href="/training/">相談</a>
</nav>
</header>
<main class="page-shell">
<section class="hero">
<div>
<p class="eyebrow">Responsive Design</p>
<h1>小さい画面から設計するClaude CodeのUI改善</h1>
<p class="lead">
mobile-first CSS、流動グリッド、レスポンシブ画像、Playwright検証を一つの流れで実装します。
</p>
<a class="primary-cta" href="/products/">プロンプト教材を見る</a>
</div>
<picture class="hero-media">
<source
type="image/avif"
srcset="/images/responsive-demo-640.avif 640w, /images/responsive-demo-1280.avif 1280w"
sizes="(width < 768px) 92vw, 40vw"
/>
<img
src="/images/responsive-demo-1280.jpg"
alt="スマホとノートPCで同じページを確認している画面"
width="1280"
height="900"
loading="eager"
decoding="async"
/>
</picture>
</section>
<div class="layout-grid">
<aside class="side-panel" aria-label="確認項目">
<h2>確認する幅</h2>
<ul>
<li>320px: 最小スマホ</li>
<li>390px: 標準スマホ</li>
<li>768px: タブレット</li>
<li>1024px以上: PC</li>
</ul>
</aside>
<section class="cards" aria-label="改善カード">
<article class="card featured">
<img src="/images/card-layout.jpg" alt="" width="720" height="480" loading="lazy" />
<div class="card-body">
<h2>カードは親幅で変える</h2>
<p>画面幅だけでなく、カード一覧が置かれたコンテナの幅に合わせて密度を変えます。</p>
</div>
</article>
<article class="card">
<div class="card-body">
<h2>ナビは折り返す</h2>
<p>スマホでは無理に横並びにせず、折り返しと十分なタップ領域を確保します。</p>
</div>
</article>
<article class="card">
<div class="card-body">
<h2>表は情報順を守る</h2>
<p>小さい画面では行をカード化し、`data-label`で列名を表示します。</p>
</div>
</article>
</section>
</div>
<section class="comparison">
<h2>プラン比較</h2>
<table class="responsive-table">
<thead>
<tr>
<th scope="col">項目</th>
<th scope="col">個人</th>
<th scope="col">チーム</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="項目">目的</td>
<td data-label="個人">学習と小さな改善</td>
<td data-label="チーム">レビュー基準の統一</td>
</tr>
<tr>
<td data-label="項目">検証</td>
<td data-label="個人">手元のPlaywright</td>
<td data-label="チーム">CIのスクリーンショット</td>
</tr>
</tbody>
</table>
</section>
</main>
</body>
</html>
mobile-first CSS、fluid grid、clamp
CSSは小さい画面を初期値にします。大きい画面だけを@mediaで足すと、スマホ側の上書きが減ります。カードの列数はrepeat(auto-fit, minmax(...))で流動化し、見出しや余白はclamp()で急な段差を避けます。
* {
box-sizing: border-box;
}
body {
margin: 0;
color: #172033;
background: #f7f8fb;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
img {
display: block;
max-width: 100%;
height: auto;
}
.site-nav,
.page-shell {
width: min(100% - 2rem, 72rem);
margin-inline: auto;
}
.site-nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
padding-block: 1rem;
}
.brand,
.nav-links a,
.primary-cta {
min-height: 44px;
display: inline-flex;
align-items: center;
}
.nav-links {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.nav-links a {
padding-inline: 0.75rem;
color: inherit;
text-decoration: none;
}
.page-shell {
padding-block: clamp(1rem, 4vw, 3rem);
}
.hero {
display: grid;
gap: clamp(1rem, 4vw, 2.5rem);
align-items: center;
}
.eyebrow {
color: #0f766e;
font-weight: 700;
}
.hero h1 {
max-width: 11ch;
margin: 0;
font-size: clamp(2.25rem, 10vw, 5rem);
line-height: 1.02;
}
.lead {
max-width: 62ch;
font-size: clamp(1rem, 2vw, 1.25rem);
line-height: 1.8;
}
.primary-cta {
width: fit-content;
border-radius: 0.5rem;
padding-inline: 1rem;
background: #172033;
color: white;
text-decoration: none;
font-weight: 700;
}
.hero-media img,
.card {
border-radius: 0.75rem;
box-shadow: 0 18px 50px rgb(15 23 42 / 0.12);
}
.layout-grid {
display: grid;
gap: clamp(1rem, 3vw, 2rem);
margin-block-start: 2rem;
}
.side-panel,
.card,
.comparison {
background: white;
border: 1px solid #dbe3ef;
border-radius: 0.75rem;
}
.side-panel {
padding: 1rem;
}
.cards {
container: cards / inline-size;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
gap: 1rem;
}
.card {
overflow: hidden;
}
.card-body {
display: grid;
gap: 0.75rem;
padding: 1rem;
}
.card h2,
.comparison h2 {
margin: 0;
font-size: clamp(1.25rem, 3vw, 1.75rem);
}
@container cards (width >= 42rem) {
.card.featured {
grid-column: span 2;
display: grid;
grid-template-columns: minmax(14rem, 0.8fr) 1fr;
}
.card.featured img {
height: 100%;
object-fit: cover;
}
}
.comparison {
margin-block-start: 2rem;
padding: 1rem;
overflow-x: auto;
}
.responsive-table {
width: 100%;
border-collapse: collapse;
}
.responsive-table th,
.responsive-table td {
padding: 0.875rem;
border-block-end: 1px solid #dbe3ef;
text-align: left;
}
@media (width < 48rem) {
.responsive-table thead {
position: absolute;
inline-size: 1px;
block-size: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
}
.responsive-table,
.responsive-table tbody,
.responsive-table tr,
.responsive-table td {
display: block;
width: 100%;
}
.responsive-table tr {
border: 1px solid #dbe3ef;
border-radius: 0.5rem;
margin-block: 0.75rem;
overflow: hidden;
}
.responsive-table td {
display: grid;
grid-template-columns: minmax(7rem, 40%) 1fr;
gap: 1rem;
}
.responsive-table td::before {
content: attr(data-label);
font-weight: 700;
color: #526071;
}
}
@media (width >= 64rem) {
.hero {
grid-template-columns: minmax(0, 1.1fr) minmax(18rem, 0.9fr);
}
.layout-grid {
grid-template-columns: 16rem minmax(0, 1fr);
}
.side-panel {
position: sticky;
top: 1rem;
align-self: start;
}
}
このCSSで重要なのは、固定幅を避けることです。width: min(100% - 2rem, 72rem)は、狭い画面では左右に余白を残し、広い画面では読みやすい最大幅で止めます。minmax(min(100%, 18rem), 1fr)は、親が狭いときにカードの最小幅が画面を突き破らないようにする保険です。
画像、ナビ、カード、テーブルの実務パターン
Claude Codeにレビューさせるときは、部品ごとの判断基準を表で渡すと抜けが減ります。
| 部品 | よくある失敗 | Claude Codeに頼む修正 |
|---|---|---|
| ナビ | PC幅の横並びをスマホに押し込む | 折り返し、十分なタップ領域、aria-labelを確認する |
| カード | width: 320pxやmin-widthで横スクロールする | auto-fit、minmax()、コンテナクエリで親幅に合わせる |
| 画像 | 大きいJPEGをスマホにも配る | srcset、sizes、width、height、loadingを入れる |
| テーブル | 列が多くて文字が潰れる | 横スクロールかカード化を選び、列名をdata-labelで残す |
| CTA | 広告や画像に埋もれる | スマホのファーストビュー下と記事末尾の両方で確認する |
実務では、すべてをハンバーガーメニューにすればよいわけではありません。リンクが3つなら折り返しの方が速いです。比較表も、金額や仕様を横に見比べる必要があるなら横スクロールが自然です。一方で、問い合わせ履歴やチケット一覧のように行単位で読む表は、スマホでカード化した方が読者の負担が減ります。
画像は特に収益に直結します。重すぎるヒーロー画像は、CTAが表示される前の離脱を増やします。Claude Codeには「画像を軽くして」ではなく、「srcsetとsizesを追加し、スマホ幅では小さい画像を選べるようにし、altが装飾画像なら空にする」と依頼すると実装が具体化します。
3つ以上のユースケース
1つ目は、SaaSダッシュボードです。サイドバー、フィルター、カード、表が混在するため、スマホでは「全部を縦に積む」だけでは使いにくくなります。Claude Codeには、重要なKPIカードを先に出し、二次フィルターを折りたたみ、詳細表はカード化するように依頼します。
2つ目は、ブログやメディアサイトです。本文幅、目次、広告、関連記事、無料PDF登録のCTAが競合します。ここでは読みやすい行長を守り、画像の遅延読み込みを入れ、CTAがコードブロックや表の直後で埋もれないかをPlaywrightで確認します。
3つ目は、ECや教材販売ページです。商品カード、価格比較、購入ボタン、FAQが重要です。スマホで価格や購入ボタンが下に流れすぎると売上に響くので、カードの順序とCTAの再掲位置をClaude Codeに明示します。
4つ目は、社内管理画面です。利用者は毎日同じ画面を繰り返し使うため、派手な見た目よりも、検索、絞り込み、キーボード操作、表の読みやすさが重要です。レスポンシブ化でも業務の順番を崩さないことを優先します。
Playwrightでスクリーンショットと横スクロールを確認する
Claude Codeの変更は、ブラウザで見て終わりにしない方が安全です。Playwrightなら、代表的な幅で横スクロールが出ていないか、ナビやCTAが表示されているか、スクリーンショット差分が想定内かを自動で確認できます。
import { expect, test } from "@playwright/test";
const baseUrl = process.env.PLAYWRIGHT_BASE_URL ?? "http://127.0.0.1:3000";
const viewports = [
{ name: "mobile-320", width: 320, height: 740 },
{ name: "mobile-390", width: 390, height: 844 },
{ name: "tablet-768", width: 768, height: 1024 },
{ name: "desktop-1440", width: 1440, height: 1000 },
];
for (const viewport of viewports) {
test(`responsive demo has no horizontal overflow at ${viewport.name}`, async ({ page }) => {
await page.setViewportSize({ width: viewport.width, height: viewport.height });
await page.goto(`${baseUrl}/responsive-demo`);
await expect(page.getByRole("navigation", { name: "メインナビゲーション" })).toBeVisible();
await expect(page.getByRole("link", { name: "プロンプト教材を見る" })).toBeVisible();
const hasHorizontalOverflow = await page.evaluate(() => {
return document.documentElement.scrollWidth > document.documentElement.clientWidth;
});
expect(hasHorizontalOverflow).toBe(false);
await expect(page).toHaveScreenshot(`responsive-${viewport.name}.png`, {
fullPage: true,
maxDiffPixels: 300,
});
});
}
最初の実行では基準画像が作られます。意図的にデザインを変えたときだけnpx playwright test --update-snapshotsで更新します。フォント、OS、GPU、ヘッドレス設定で見た目が変わることがあるため、CIで比較するなら同じ環境で基準画像を作るのが基本です。
失敗例と落とし穴
よくある失敗は、デスクトップ用CSSの最後にスマホ用CSSを足し続けることです。上書きが増えるほど、どの幅で何が効くのか読みにくくなります。Claude Codeに修正させるときは「小さい画面の初期値に戻し、広い画面だけ追加する」と明示します。
次に、<meta name="viewport">の抜けです。これがないと、スマホのブラウザがページを広い仮想幅で表示し、CSSの意図と実機表示がズレます。HTMLテンプレートやレイアウトコンポーネントに入っているか確認してください。
3つ目は、カードや表に固定幅を残すことです。min-width: 960pxのような指定は、PCでは気づきにくく、スマホで横スクロールを生みます。どうしても表を横スクロールにする場合も、ページ全体ではなく表のラッパーだけにoverflow-x: autoを設定します。
4つ目は、画像のsrcsetだけを書いてsizesを忘れることです。ブラウザが表示サイズを判断しにくくなり、想定より大きな画像が選ばれることがあります。画像をレスポンシブ化するときは、srcset、sizes、width、height、altを一緒に確認します。
5つ目は、スクリーンショットテストを過信することです。スクリーンショットは視覚差分に強い一方で、動的な広告、日付、アニメーションに弱いです。必要に応じてテスト用CSSで揺れる要素を隠し、横スクロールや要素の可視性のようなDOMベースの検証も組み合わせます。
収益導線まで含めて改善する
レスポンシブ対応は、見た目の改善だけではなく、売上や問い合わせ導線の改善でもあります。スマホ読者が多い記事なら、無料PDF、Gumroad教材、研修相談への導線が小さい画面で見つけやすいかを必ず確認します。
ClaudeCodeLabでは、実装を自分で進めたい人向けにClaude Code教材・プロンプト集を用意しています。チームの既存画面を題材に、レスポンシブ改善、レビュー観点、Playwright検証まで一緒に整えたい場合はClaude Code研修・相談が向いています。記事のPVだけを追うのではなく、「読まれた後に何をしてもらうか」まで設計すると、レスポンシブ化の優先順位が決めやすくなります。
まとめ
Claude Codeでレスポンシブデザインを実装するときは、mobile-first CSS、fluid grid、clamp()、コンテナクエリ、レスポンシブ画像、ナビ、カード、テーブル、Playwright検証を一つの流れとして扱います。「スマホ対応して」ではなく、「どの幅で、どの部品を、どう検証するか」まで渡すのが実務のコツです。
この記事で紹介した内容を実際にローカルのデモページで試した結果、320pxと390pxではナビが折り返し、カードは1列、表は行カードとして読めました。768px以上ではカードの密度が上がり、1440pxでは本文幅が広がりすぎず、Playwrightの横スクロール検証も通りました。Masaの実感としては、Claude Codeには実装だけでなく「固定幅、画像、CTA、表、スクリーンショット差分を疑うレビュー役」まで任せると、公開前の手戻りがかなり減ります。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Code権限セーフティラダー: 初心者がallowを広げる順番
Claude Codeの権限をread-onlyからbuild、限定編集、deploy確認まで段階的に広げる安全な運用手順。
Claude Code Small PR Proof Pack: 小さなPRをレビュー可能にする証拠セット
Claude Codeの小さなPRに、差分・検証・公開URL・CTA・rollbackを添える実務チェックリスト。
Claude Codeのコミット前レビューゲート: 差分、テスト、CTAをまとめて止める型
Claude Codeでcommit前に差分をレビューする実践手順。build、公開URL、CTA、Gumroadリンク、未翻訳本文を検知します。