アプリシェル(サイドバー+ヘッダー)
管理画面の定番構成。左サイドバー・上ヘッダー・メインを CSS Grid の grid-template-areas で組み、ボタンでサイドバーを畳んで表示領域を広げられる。
ライブデモ
コード
HTML
<!-- アプリシェル:サイドバー+ヘッダーを CSS Grid の grid-template-areas で構成 -->
<div class="ash" id="ashRoot">
<aside class="ash__sidebar">
<div class="ash__brand">
<span class="ash__brand-icon">◆</span>
<span class="ash__brand-text">Nimbus</span>
</div>
<nav class="ash__nav">
<a class="is-active" href="#">
<span class="ash__navicon">📊</span><span class="ash__navtext">ダッシュボード</span>
</a>
<a href="#">
<span class="ash__navicon">📁</span><span class="ash__navtext">プロジェクト</span>
</a>
<a href="#">
<span class="ash__navicon">👥</span><span class="ash__navtext">チーム</span>
</a>
<a href="#">
<span class="ash__navicon">💳</span><span class="ash__navtext">請求</span>
</a>
<a href="#">
<span class="ash__navicon">⚙️</span><span class="ash__navtext">設定</span>
</a>
</nav>
</aside>
<header class="ash__header">
<button class="ash__toggle" id="ashToggle" type="button" aria-label="サイドバーの折りたたみ切替" aria-expanded="true">
<span></span><span></span><span></span>
</button>
<span class="ash__title">ダッシュボード</span>
<span class="ash__user">田中 ◉</span>
</header>
<main class="ash__main">
<div class="ash__kpis">
<div class="ash-kpi"><span>今月の売上</span><b>¥1.24M</b><i class="up">+12%</i></div>
<div class="ash-kpi"><span>新規契約</span><b>48</b><i class="up">+6%</i></div>
<div class="ash-kpi"><span>解約率</span><b>1.8%</b><i class="down">-0.3%</i></div>
</div>
<div class="ash__panel">
<p class="ash__panel-h">最近のアクティビティ</p>
<ul class="ash__feed">
<li><span class="dot dot--b"></span>佐藤さんが「請求API」タスクを完了しました</li>
<li><span class="dot dot--g"></span>新規プロジェクト「Q3刷新」が作成されました</li>
<li><span class="dot"></span>山田さんがレポートにコメントを追加しました</li>
</ul>
</div>
</main>
</div>
CSS
/* 全体:明るいSaaSダッシュボード風。CSS Grid の grid-template-areas でシェルを構成 */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: "Hiragino Sans", system-ui, sans-serif;
background: #eef1f7;
color: #1c2333;
min-height: 100vh;
display: block; /* ビルダーの flex 中央寄せを解除し、フルブリードのシェルを表示 */
}
/* ルート:width:100% が無いと親の flex 中央寄せでグリッドが潰れるため必須 */
.ash {
width: 100%;
min-height: 100vh;
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: 56px 1fr;
grid-template-areas:
"side head"
"side main";
transition: grid-template-columns .22s ease;
}
/* サイドバー */
.ash__sidebar {
grid-area: side;
background: #14192b;
color: #cbd3e6;
padding: 16px 14px;
display: flex; flex-direction: column; gap: 18px;
overflow: hidden;
}
.ash__brand { display: flex; align-items: center; gap: 8px; padding: 0 6px; white-space: nowrap; }
.ash__brand-icon { color: #7dd3fc; font-size: 18px; }
.ash__brand-text { font-weight: 800; letter-spacing: .04em; color: #f1f5f9; }
.ash__nav { display: flex; flex-direction: column; gap: 4px; }
.ash__nav a {
display: flex; align-items: center; gap: 10px; white-space: nowrap;
color: #aab3ca; text-decoration: none; font-size: 13px; font-weight: 600;
padding: 9px 10px; border-radius: 9px; transition: background .18s, color .18s;
}
.ash__nav a:hover { background: #1d2440; color: #e2e8f0; }
.ash__nav a.is-active { background: #223056; color: #7dd3fc; }
.ash__navicon { font-size: 15px; width: 18px; text-align: center; flex-shrink: 0; }
/* ヘッダー */
.ash__header {
grid-area: head;
display: flex; align-items: center; gap: 12px;
padding: 0 18px; background: #ffffff; border-bottom: 1px solid #e2e8f0;
}
.ash__toggle {
width: 30px; height: 30px; border-radius: 8px; border: 1px solid #dde3ee;
background: #fff; cursor: pointer; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 4px; flex-shrink: 0;
}
.ash__toggle span { width: 14px; height: 2px; background: #47506b; border-radius: 2px; }
.ash__toggle:hover { background: #f3f5f9; }
.ash__title { font-weight: 800; font-size: 14px; color: #1c2333; }
.ash__user { margin-left: auto; font-size: 13px; color: #5b6478; font-weight: 600; }
/* メイン */
.ash__main { grid-area: main; padding: 20px 22px; overflow: auto; }
.ash__kpis { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 16px; }
.ash-kpi {
flex: 1 1 140px; background: #fff; border: 1px solid #e6eaf2; border-radius: 12px;
padding: 12px 14px; display: flex; flex-direction: column; gap: 4px;
}
.ash-kpi span { font-size: 11px; color: #7c869c; font-weight: 700; letter-spacing: .03em; }
.ash-kpi b { font-size: 20px; color: #161c2c; }
.ash-kpi i { font-size: 11px; font-weight: 700; font-style: normal; width: fit-content; padding: 1px 6px; border-radius: 20px; }
.ash-kpi i.up { color: #059669; background: #d1fae5; }
.ash-kpi i.down { color: #dc2626; background: #fee2e2; }
.ash__panel { background: #fff; border: 1px solid #e6eaf2; border-radius: 12px; padding: 16px; }
.ash__panel-h { font-size: 12px; font-weight: 800; color: #47506b; margin-bottom: 10px; }
.ash__feed { list-style: none; display: flex; flex-direction: column; gap: 9px; }
.ash__feed li { display: flex; align-items: center; gap: 9px; font-size: 13px; color: #333c50; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: #94a3b8; flex-shrink: 0; }
.dot--b { background: #38bdf8; }
.dot--g { background: #34d399; }
/* 折りたたみ:ボタンでアイコンレールに縮小(is-collapsed は JS が root に付け外し) */
.ash.is-collapsed { grid-template-columns: 60px 1fr; }
.ash.is-collapsed .ash__brand-text,
.ash.is-collapsed .ash__navtext { display: none; }
.ash.is-collapsed .ash__nav a { justify-content: center; }
.ash.is-collapsed .ash__brand { justify-content: center; }
/* 狭幅では初期状態からアイコンレールにし、トグルでさらに完全に隠せる */
@media (max-width: 640px) {
.ash { grid-template-columns: 60px 1fr; }
.ash__brand-text, .ash__navtext { display: none; }
.ash__nav a { justify-content: center; }
.ash__brand { justify-content: center; }
.ash.is-collapsed { grid-template-columns: 0px 1fr; }
.ash.is-collapsed .ash__sidebar { padding: 0; overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) {
.ash { transition: none; }
.ash__nav a { transition: none; }
}
JavaScript
// サイドバー折りたたみトグル+ナビのアクティブ切替(null安全)
(() => {
const root = document.getElementById('ashRoot');
const toggle = document.getElementById('ashToggle');
if (!root || !toggle) return;
toggle.addEventListener('click', () => {
const collapsed = root.classList.toggle('is-collapsed');
toggle.setAttribute('aria-expanded', String(!collapsed));
});
const links = root.querySelectorAll('.ash__nav a');
links.forEach((link) => {
link.addEventListener('click', (e) => {
e.preventDefault();
links.forEach((l) => l.classList.remove('is-active'));
link.classList.add('is-active');
});
});
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「アプリシェル(サイドバー+ヘッダー)」の効果を追加してください。
# 追加してほしい効果
アプリシェル(サイドバー+ヘッダー)(レイアウト & グリッド)
管理画面の定番構成。左サイドバー・上ヘッダー・メインを CSS Grid の grid-template-areas で組み、ボタンでサイドバーを畳んで表示領域を広げられる。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- アプリシェル:サイドバー+ヘッダーを CSS Grid の grid-template-areas で構成 -->
<div class="ash" id="ashRoot">
<aside class="ash__sidebar">
<div class="ash__brand">
<span class="ash__brand-icon">◆</span>
<span class="ash__brand-text">Nimbus</span>
</div>
<nav class="ash__nav">
<a class="is-active" href="#">
<span class="ash__navicon">📊</span><span class="ash__navtext">ダッシュボード</span>
</a>
<a href="#">
<span class="ash__navicon">📁</span><span class="ash__navtext">プロジェクト</span>
</a>
<a href="#">
<span class="ash__navicon">👥</span><span class="ash__navtext">チーム</span>
</a>
<a href="#">
<span class="ash__navicon">💳</span><span class="ash__navtext">請求</span>
</a>
<a href="#">
<span class="ash__navicon">⚙️</span><span class="ash__navtext">設定</span>
</a>
</nav>
</aside>
<header class="ash__header">
<button class="ash__toggle" id="ashToggle" type="button" aria-label="サイドバーの折りたたみ切替" aria-expanded="true">
<span></span><span></span><span></span>
</button>
<span class="ash__title">ダッシュボード</span>
<span class="ash__user">田中 ◉</span>
</header>
<main class="ash__main">
<div class="ash__kpis">
<div class="ash-kpi"><span>今月の売上</span><b>¥1.24M</b><i class="up">+12%</i></div>
<div class="ash-kpi"><span>新規契約</span><b>48</b><i class="up">+6%</i></div>
<div class="ash-kpi"><span>解約率</span><b>1.8%</b><i class="down">-0.3%</i></div>
</div>
<div class="ash__panel">
<p class="ash__panel-h">最近のアクティビティ</p>
<ul class="ash__feed">
<li><span class="dot dot--b"></span>佐藤さんが「請求API」タスクを完了しました</li>
<li><span class="dot dot--g"></span>新規プロジェクト「Q3刷新」が作成されました</li>
<li><span class="dot"></span>山田さんがレポートにコメントを追加しました</li>
</ul>
</div>
</main>
</div>
【CSS】
/* 全体:明るいSaaSダッシュボード風。CSS Grid の grid-template-areas でシェルを構成 */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: "Hiragino Sans", system-ui, sans-serif;
background: #eef1f7;
color: #1c2333;
min-height: 100vh;
display: block; /* ビルダーの flex 中央寄せを解除し、フルブリードのシェルを表示 */
}
/* ルート:width:100% が無いと親の flex 中央寄せでグリッドが潰れるため必須 */
.ash {
width: 100%;
min-height: 100vh;
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: 56px 1fr;
grid-template-areas:
"side head"
"side main";
transition: grid-template-columns .22s ease;
}
/* サイドバー */
.ash__sidebar {
grid-area: side;
background: #14192b;
color: #cbd3e6;
padding: 16px 14px;
display: flex; flex-direction: column; gap: 18px;
overflow: hidden;
}
.ash__brand { display: flex; align-items: center; gap: 8px; padding: 0 6px; white-space: nowrap; }
.ash__brand-icon { color: #7dd3fc; font-size: 18px; }
.ash__brand-text { font-weight: 800; letter-spacing: .04em; color: #f1f5f9; }
.ash__nav { display: flex; flex-direction: column; gap: 4px; }
.ash__nav a {
display: flex; align-items: center; gap: 10px; white-space: nowrap;
color: #aab3ca; text-decoration: none; font-size: 13px; font-weight: 600;
padding: 9px 10px; border-radius: 9px; transition: background .18s, color .18s;
}
.ash__nav a:hover { background: #1d2440; color: #e2e8f0; }
.ash__nav a.is-active { background: #223056; color: #7dd3fc; }
.ash__navicon { font-size: 15px; width: 18px; text-align: center; flex-shrink: 0; }
/* ヘッダー */
.ash__header {
grid-area: head;
display: flex; align-items: center; gap: 12px;
padding: 0 18px; background: #ffffff; border-bottom: 1px solid #e2e8f0;
}
.ash__toggle {
width: 30px; height: 30px; border-radius: 8px; border: 1px solid #dde3ee;
background: #fff; cursor: pointer; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 4px; flex-shrink: 0;
}
.ash__toggle span { width: 14px; height: 2px; background: #47506b; border-radius: 2px; }
.ash__toggle:hover { background: #f3f5f9; }
.ash__title { font-weight: 800; font-size: 14px; color: #1c2333; }
.ash__user { margin-left: auto; font-size: 13px; color: #5b6478; font-weight: 600; }
/* メイン */
.ash__main { grid-area: main; padding: 20px 22px; overflow: auto; }
.ash__kpis { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 16px; }
.ash-kpi {
flex: 1 1 140px; background: #fff; border: 1px solid #e6eaf2; border-radius: 12px;
padding: 12px 14px; display: flex; flex-direction: column; gap: 4px;
}
.ash-kpi span { font-size: 11px; color: #7c869c; font-weight: 700; letter-spacing: .03em; }
.ash-kpi b { font-size: 20px; color: #161c2c; }
.ash-kpi i { font-size: 11px; font-weight: 700; font-style: normal; width: fit-content; padding: 1px 6px; border-radius: 20px; }
.ash-kpi i.up { color: #059669; background: #d1fae5; }
.ash-kpi i.down { color: #dc2626; background: #fee2e2; }
.ash__panel { background: #fff; border: 1px solid #e6eaf2; border-radius: 12px; padding: 16px; }
.ash__panel-h { font-size: 12px; font-weight: 800; color: #47506b; margin-bottom: 10px; }
.ash__feed { list-style: none; display: flex; flex-direction: column; gap: 9px; }
.ash__feed li { display: flex; align-items: center; gap: 9px; font-size: 13px; color: #333c50; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: #94a3b8; flex-shrink: 0; }
.dot--b { background: #38bdf8; }
.dot--g { background: #34d399; }
/* 折りたたみ:ボタンでアイコンレールに縮小(is-collapsed は JS が root に付け外し) */
.ash.is-collapsed { grid-template-columns: 60px 1fr; }
.ash.is-collapsed .ash__brand-text,
.ash.is-collapsed .ash__navtext { display: none; }
.ash.is-collapsed .ash__nav a { justify-content: center; }
.ash.is-collapsed .ash__brand { justify-content: center; }
/* 狭幅では初期状態からアイコンレールにし、トグルでさらに完全に隠せる */
@media (max-width: 640px) {
.ash { grid-template-columns: 60px 1fr; }
.ash__brand-text, .ash__navtext { display: none; }
.ash__nav a { justify-content: center; }
.ash__brand { justify-content: center; }
.ash.is-collapsed { grid-template-columns: 0px 1fr; }
.ash.is-collapsed .ash__sidebar { padding: 0; overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) {
.ash { transition: none; }
.ash__nav a { transition: none; }
}
【JavaScript】
// サイドバー折りたたみトグル+ナビのアクティブ切替(null安全)
(() => {
const root = document.getElementById('ashRoot');
const toggle = document.getElementById('ashToggle');
if (!root || !toggle) return;
toggle.addEventListener('click', () => {
const collapsed = root.classList.toggle('is-collapsed');
toggle.setAttribute('aria-expanded', String(!collapsed));
});
const links = root.querySelectorAll('.ash__nav a');
links.forEach((link) => {
link.addEventListener('click', (e) => {
e.preventDefault();
links.forEach((l) => l.classList.remove('is-active'));
link.classList.add('is-active');
});
});
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。