モダンレイアウト
ヘッダー、サイドバー、フッターなど現代的なサイト構成
モダンなWebサイトの構成
基本的なレイアウトパターン
ヘッダー + コンテンツ
ブログ、ニュースサイト
シンプルなWebサイト
サイドバー付き
管理画面、ドキュメント
このサイトのような構成
フルスクリーン
ランディングページ
アプリケーション
基本レイアウト(ヘッダー・フッター)
Sticky Header + Footer
上固定ヘッダーとフッター
html
<div class="min-h-screen flex flex-col">
<!-- ヘッダー(上に固定) -->
<header class="sticky top-0 z-50 bg-white border-b shadow-sm">
<div class="max-w-7xl mx-auto px-4 py-3 flex items-center justify-between">
<a href="/" class="text-xl font-bold">Logo</a>
<nav class="flex gap-6">
<a href="/" class="hover:text-blue-600">ホーム</a>
<a href="/about" class="hover:text-blue-600">About</a>
<a href="/contact" class="hover:text-blue-600">お問い合わせ</a>
</nav>
</div>
</header>
<!-- メインコンテンツ(残りのスペースを埋める) -->
<main class="flex-1 max-w-7xl mx-auto px-4 py-8 w-full">
<h1>コンテンツ</h1>
</main>
<!-- フッター(常に下に) -->
<footer class="bg-gray-100 border-t">
<div class="max-w-7xl mx-auto px-4 py-6">
<p class="text-center text-gray-600">© 2024 My Website</p>
</div>
</footer>
</div>プレビュー
コード解説:ヘッダー・フッターレイアウト
① 全体の構造
<div class="min-h-screen flex flex-col">
min-h-screen:画面全体の高さを確保(100vh)flex flex-col:中身を縦に並べる(ヘッダー→本文→フッター)
② 固定ヘッダー
<header class="sticky top-0 z-50 bg-white border-b shadow-sm">
sticky top-0:スクロールしても上部に固定されるz-50:他の要素より前面に表示(重なり順)
③ メインコンテンツ
<main class="flex-1 max-w-7xl mx-auto px-4 py-8 w-full">
flex-1:残りの高さをすべて使う(フッターを下に押す)max-w-7xl mx-auto:最大幅を制限して中央に配置
なぜこのパターン?
コンテンツが少なくてもflex-1のおかげでフッターは常に画面下部に配置されます。
サイドバーレイアウト
固定サイドバー
管理画面・ドキュメントサイト向け
html
<div class="flex min-h-screen">
<!-- サイドバー(固定幅) -->
<aside class="w-64 bg-gray-900 text-white flex-shrink-0">
<div class="p-4">
<h1 class="text-xl font-bold mb-6">Admin</h1>
<nav class="space-y-2">
<a href="/dashboard" class="block px-4 py-2 rounded-lg bg-gray-800 hover:bg-gray-700">
ダッシュボード
</a>
<a href="/users" class="block px-4 py-2 rounded-lg hover:bg-gray-700">
ユーザー
</a>
<a href="/settings" class="block px-4 py-2 rounded-lg hover:bg-gray-700">
設定
</a>
</nav>
</div>
</aside>
<!-- メインエリア -->
<div class="flex-1 flex flex-col">
<!-- ヘッダー -->
<header class="bg-white border-b px-6 py-4 flex items-center justify-between">
<h2 class="text-lg font-semibold">ダッシュボード</h2>
<div class="flex items-center gap-4">
<span>田中さん</span>
<button>ログアウト</button>
</div>
</header>
<!-- コンテンツ -->
<main class="flex-1 p-6 bg-gray-50">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- カード -->
</div>
</main>
</div>
</div>プレビュー
コード解説:各クラスの役割
① 全体のコンテナ
<div class="flex min-h-screen">
flex:子要素を横並びにする(Flexbox)min-h-screen:最低でも画面の高さを確保(100vh)
② サイドバー
<aside class="w-64 bg-gray-900 text-white flex-shrink-0">
w-64:幅256px固定(16rem × 16px)bg-gray-900 text-white:暗い背景色と白文字flex-shrink-0:画面が狭くなっても縮まない
③ ナビゲーションリンク
<a class="block px-4 py-2 rounded-lg hover:bg-gray-700">
block:ブロック要素に(クリック範囲が広がる)px-4 py-2:左右16px、上下8pxの余白rounded-lg:角を丸く(8px)hover:bg-gray-700:マウスを乗せた時に背景色変更
④ メインエリア
<div class="flex-1 flex flex-col">
flex-1:残りの幅すべてを占めるflex flex-col:中を縦並びに(ヘッダー→コンテンツ)
⑤ ヘッダー
<header class="bg-white border-b px-6 py-4 flex items-center justify-between">
border-b:下に線を引くflex items-center justify-between:左右に要素を配置、縦中央揃え
⑥ コンテンツエリア
<main class="flex-1 p-6 bg-gray-50">
flex-1:残りの高さをすべて使うbg-gray-50:薄いグレーの背景
組み立て結果
サイドバー(256px固定)が左に、残りのスペースにヘッダー+コンテンツが縦に並び、画面全体を埋めるレイアウトが完成します。
折りたたみ可能なサイドバー
モバイル対応
svelte
<script>
let sidebarOpen = $state(false);
</script>
<div class="flex min-h-screen">
<!-- オーバーレイ(モバイル時) -->
{#if sidebarOpen}
<div
class="fixed inset-0 bg-black/50 z-40 lg:hidden"
onclick={() => sidebarOpen = false}
></div>
{/if}
<!-- サイドバー -->
<aside class="
fixed lg:static inset-y-0 left-0 z-50
w-64 bg-gray-900 text-white
transform transition-transform duration-300
{sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}
">
<!-- サイドバーの中身 -->
</aside>
<!-- メインエリア -->
<div class="flex-1">
<header class="bg-white border-b px-4 py-3">
<!-- ハンバーガーメニュー(モバイル時のみ) -->
<button
class="lg:hidden p-2"
onclick={() => sidebarOpen = true}
>
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</header>
<main class="p-6">
<!-- コンテンツ -->
</main>
</div>
</div>プレビュー
// PC: サイドバー常に表示
// モバイル: ハンバーガーメニューで開閉
// lg:hidden / lg:translate-x-0 で切り替え
ナビゲーションパターン
レスポンシブナビゲーション
PC:横並び / モバイル:ハンバーガー
svelte
<script>
let menuOpen = $state(false);
</script>
<header class="bg-white shadow-sm">
<div class="max-w-7xl mx-auto px-4">
<div class="flex items-center justify-between h-16">
<!-- ロゴ -->
<a href="/" class="text-xl font-bold">Logo</a>
<!-- デスクトップナビ -->
<nav class="hidden md:flex items-center gap-6">
<a href="/" class="hover:text-blue-600">ホーム</a>
<a href="/products" class="hover:text-blue-600">製品</a>
<a href="/about" class="hover:text-blue-600">会社概要</a>
<a href="/contact" class="px-4 py-2 bg-blue-600 text-white rounded-lg">
お問い合わせ
</a>
</nav>
<!-- モバイルメニューボタン -->
<button
class="md:hidden p-2"
onclick={() => menuOpen = !menuOpen}
>
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
{#if menuOpen}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
{:else}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
{/if}
</svg>
</button>
</div>
<!-- モバイルナビ -->
{#if menuOpen}
<nav class="md:hidden py-4 border-t">
<a href="/" class="block py-2">ホーム</a>
<a href="/products" class="block py-2">製品</a>
<a href="/about" class="block py-2">会社概要</a>
<a href="/contact" class="block py-2 mt-2 text-center bg-blue-600 text-white rounded-lg">
お問い合わせ
</a>
</nav>
{/if}
</div>
</header>プレビュー
タブナビゲーション
セクション切り替え
svelte
<script>
let activeTab = $state('overview');
</script>
<div class="border-b border-gray-200">
<nav class="flex gap-8">
<button
class="py-4 px-1 border-b-2 font-medium text-sm
{activeTab === 'overview'
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700'}"
onclick={() => activeTab = 'overview'}
>
概要
</button>
<button
class="py-4 px-1 border-b-2 font-medium text-sm
{activeTab === 'features'
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700'}"
onclick={() => activeTab = 'features'}
>
機能
</button>
<button
class="py-4 px-1 border-b-2 font-medium text-sm
{activeTab === 'pricing'
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700'}"
onclick={() => activeTab = 'pricing'}
>
料金
</button>
</nav>
</div>
<div class="py-6">
{#if activeTab === 'overview'}
<p>概要コンテンツ</p>
{:else if activeTab === 'features'}
<p>機能コンテンツ</p>
{:else}
<p>料金コンテンツ</p>
{/if}
</div>プレビュー
概要機能料金
フッターパターン
マルチカラムフッター
リンク集+コピーライト
html
<footer class="bg-gray-900 text-gray-300">
<div class="max-w-7xl mx-auto px-4 py-12">
<!-- リンクセクション -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 mb-8">
<!-- 会社情報 -->
<div>
<h3 class="text-white font-semibold mb-4">Company</h3>
<ul class="space-y-2 text-sm">
<li><a href="/about" class="hover:text-white">会社概要</a></li>
<li><a href="/careers" class="hover:text-white">採用情報</a></li>
<li><a href="/news" class="hover:text-white">ニュース</a></li>
</ul>
</div>
<!-- 製品 -->
<div>
<h3 class="text-white font-semibold mb-4">Products</h3>
<ul class="space-y-2 text-sm">
<li><a href="/features" class="hover:text-white">機能</a></li>
<li><a href="/pricing" class="hover:text-white">料金</a></li>
<li><a href="/demo" class="hover:text-white">デモ</a></li>
</ul>
</div>
<!-- サポート -->
<div>
<h3 class="text-white font-semibold mb-4">Support</h3>
<ul class="space-y-2 text-sm">
<li><a href="/docs" class="hover:text-white">ドキュメント</a></li>
<li><a href="/faq" class="hover:text-white">FAQ</a></li>
<li><a href="/contact" class="hover:text-white">お問い合わせ</a></li>
</ul>
</div>
<!-- 法的情報 -->
<div>
<h3 class="text-white font-semibold mb-4">Legal</h3>
<ul class="space-y-2 text-sm">
<li><a href="/privacy" class="hover:text-white">プライバシー</a></li>
<li><a href="/terms" class="hover:text-white">利用規約</a></li>
</ul>
</div>
</div>
<!-- 区切り線 -->
<div class="border-t border-gray-800 pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
<p class="text-sm">© 2024 Company. All rights reserved.</p>
<!-- SNSリンク -->
<div class="flex gap-4">
<a href="#" class="hover:text-white">Twitter</a>
<a href="#" class="hover:text-white">GitHub</a>
<a href="#" class="hover:text-white">Discord</a>
</div>
</div>
</div>
</footer>プレビュー
Company
会社概要
採用情報
Products
機能
料金
Support
ドキュメント
FAQ
Legal
プライバシー
利用規約
© 2024 Company
Twitter GitHub
カードレイアウト
レスポンシブカードグリッド
画面サイズで列数が変わる
html
<!-- モバイル:1列 / タブレット:2列 / PC:3列 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- カード -->
<div class="bg-white rounded-xl shadow-sm border overflow-hidden hover:shadow-md transition-shadow">
<img src="/image.jpg" alt="" class="w-full h-48 object-cover" />
<div class="p-6">
<span class="text-xs font-medium text-blue-600 bg-blue-50 px-2 py-1 rounded">
カテゴリ
</span>
<h3 class="mt-3 text-lg font-semibold">タイトル</h3>
<p class="mt-2 text-gray-600 text-sm line-clamp-2">
説明文がここに入ります。長い場合は2行で切り詰められます。
</p>
<div class="mt-4 flex items-center justify-between">
<span class="text-sm text-gray-500">2024/01/15</span>
<a href="#" class="text-blue-600 text-sm font-medium hover:underline">
詳しく見る →
</a>
</div>
</div>
</div>
<!-- 他のカード... -->
</div>プレビュー
コード解説:カードグリッドの仕組み
① グリッドコンテナ(レスポンシブ)
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
grid:CSS Gridレイアウトを有効化grid-cols-1:デフォルトで1列(モバイル)md:grid-cols-2:768px以上で2列lg:grid-cols-3:1024px以上で3列gap-6:カード間の隙間(24px)
② カード本体
<div class="bg-white rounded-xl shadow-sm border overflow-hidden hover:shadow-md transition-shadow">
rounded-xl:大きめの角丸(12px)shadow-sm:軽い影overflow-hidden:角丸から画像がはみ出ないようにhover:shadow-md transition-shadow:ホバー時に影を大きく(アニメーション付き)
③ 画像
<img class="w-full h-48 object-cover">
w-full:横幅いっぱいh-48:高さ192px固定object-cover:縦横比を保ちつつ領域を埋める(トリミング)
④ カテゴリバッジ
<span class="text-xs font-medium text-blue-600 bg-blue-50 px-2 py-1 rounded">
text-xs:小さい文字text-blue-600 bg-blue-50:青文字に薄い青背景
⑤ フッター部分
<div class="flex items-center justify-between">
flex items-center justify-between:日付を左、リンクを右に配置
覚えておきたいパターン
中央寄せコンテナ
max-w-7xl mx-auto px-4 最大幅を制限して中央に配置、左右に余白
画面全体を埋める
min-h-screen flex flex-col フッターを常に画面下に配置
上に固定
sticky top-0 z-50 スクロールしても上部に固定
残りを埋める
flex-1 Flexbox内で残りのスペースを占める
PC/モバイル切り替え
hidden md:flex / md:hidden 画面サイズで表示/非表示を切り替え