オートフィット・カードグリッド
grid-template-columns の repeat(auto-fit, minmax()) で列数が自動増減するカードグリッド。幅ボタンで折返しの変化を確認できる。
ライブデモ
コード
HTML
<!-- オートフィット・カードグリッド:repeat(auto-fit, minmax()) で列数が自動増減 -->
<div class="afc" id="afcRoot">
<div class="afc__toolbar">
<p class="afc__label">コンテナ幅</p>
<div class="afc__btns">
<button type="button" data-width="narrow">狭い</button>
<button type="button" data-width="medium" class="is-active">中</button>
<button type="button" data-width="wide">広い</button>
</div>
</div>
<div class="afc__stage">
<div class="afc__grid" id="afcGrid">
<div class="afc-card"><span class="afc-card__no">01</span><p>ダッシュボード</p></div>
<div class="afc-card"><span class="afc-card__no">02</span><p>プロジェクト管理</p></div>
<div class="afc-card"><span class="afc-card__no">03</span><p>チームメンバー</p></div>
<div class="afc-card"><span class="afc-card__no">04</span><p>請求と支払い</p></div>
<div class="afc-card"><span class="afc-card__no">05</span><p>通知設定</p></div>
<div class="afc-card"><span class="afc-card__no">06</span><p>アクセス権限</p></div>
<div class="afc-card"><span class="afc-card__no">07</span><p>レポート出力</p></div>
<div class="afc-card"><span class="afc-card__no">08</span><p>APIキー管理</p></div>
</div>
</div>
</div>
CSS
/* 全体:カードグリッドの折返しをコンテナ幅トグルで実演 */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: "Hiragino Sans", system-ui, sans-serif;
background: #f4f6fb;
color: #1b2233;
min-height: 100vh;
display: flex; align-items: center; justify-content: center;
padding: 20px;
}
/* ルート:width:100% が無いと親の flex 中央寄せで潰れ、auto-fit の列計算も崩れるため必須 */
.afc { width: 100%; max-width: 920px; }
.afc__toolbar {
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
margin-bottom: 16px;
}
.afc__label { font-size: 12px; font-weight: 800; color: #5b6478; }
.afc__btns { display: flex; gap: 6px; }
.afc__btns button {
font-size: 12.5px; font-weight: 700; padding: 7px 14px; border-radius: 999px;
border: 1px solid #d8dee9; background: #fff; color: #47506b; cursor: pointer;
transition: background .15s, color .15s, border-color .15s;
}
.afc__btns button:hover { background: #eef2ff; }
.afc__btns button.is-active { background: #4338ca; border-color: #4338ca; color: #fff; }
.afc__stage {
border: 1px dashed #c7cfdf; border-radius: 16px; padding: 20px;
display: flex; justify-content: center; overflow: hidden;
}
/* 列数はここで自動計算される:コンテナ幅 ÷ minmax の下限で決まる */
.afc__grid {
width: var(--afc-w, 290px); /* 初期値は「中」ボタンと一致させる(既定選択との齟齬を防ぐ) */
max-width: 100%;
display: grid;
/* カード下限を 110px と小さめにして、狭いプレビュー(一覧カード約393px幅)でも 1→2→3 列の変化が出せるようにする */
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
gap: 14px;
transition: width .3s ease;
}
.afc-card {
background: #fff; border: 1px solid #e6eaf2; border-radius: 12px;
padding: 18px 14px; display: flex; flex-direction: column; gap: 8px;
box-shadow: 0 10px 24px -18px rgba(15, 23, 42, .4);
}
.afc-card__no { font-size: 11px; font-weight: 800; letter-spacing: .1em; color: #a5adc0; }
.afc-card p { font-size: 13.5px; font-weight: 700; color: #262d3f; }
@media (prefers-reduced-motion: reduce) {
.afc__grid { transition: none; }
.afc__btns button { transition: none; }
}
JavaScript
// コンテナ幅トグル:ボタンでグリッドの幅を変え、auto-fit の折返しを実演(null安全)
(() => {
const grid = document.getElementById('afcGrid');
const root = document.getElementById('afcRoot');
if (!grid || !root) return;
// 各段でグリッドの列数が確実に変わる幅にする:狭い=1列 / 中=2列 / 広い=コンテナ一杯(3列以上)。
// 親より広い値は max-width:100% でコンテナ幅に丸められ「中」と「広い」が同化するため、狭い一覧カード
// (グリッド領域 約393px)でも収まる 170/290px にする。minmax(110px) と組で 170→1列・290→2列・100%→3列。
const widths = { narrow: '170px', medium: '290px', wide: '100%' };
const buttons = root.querySelectorAll('[data-width]');
if (!buttons.length) return;
buttons.forEach((btn) => {
btn.addEventListener('click', () => {
const key = btn.getAttribute('data-width');
const w = widths[key] || widths.medium;
grid.style.setProperty('--afc-w', w);
buttons.forEach((b) => b.classList.remove('is-active'));
btn.classList.add('is-active');
});
});
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「オートフィット・カードグリッド」の効果を追加してください。
# 追加してほしい効果
オートフィット・カードグリッド(レイアウト & グリッド)
grid-template-columns の repeat(auto-fit, minmax()) で列数が自動増減するカードグリッド。幅ボタンで折返しの変化を確認できる。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- オートフィット・カードグリッド:repeat(auto-fit, minmax()) で列数が自動増減 -->
<div class="afc" id="afcRoot">
<div class="afc__toolbar">
<p class="afc__label">コンテナ幅</p>
<div class="afc__btns">
<button type="button" data-width="narrow">狭い</button>
<button type="button" data-width="medium" class="is-active">中</button>
<button type="button" data-width="wide">広い</button>
</div>
</div>
<div class="afc__stage">
<div class="afc__grid" id="afcGrid">
<div class="afc-card"><span class="afc-card__no">01</span><p>ダッシュボード</p></div>
<div class="afc-card"><span class="afc-card__no">02</span><p>プロジェクト管理</p></div>
<div class="afc-card"><span class="afc-card__no">03</span><p>チームメンバー</p></div>
<div class="afc-card"><span class="afc-card__no">04</span><p>請求と支払い</p></div>
<div class="afc-card"><span class="afc-card__no">05</span><p>通知設定</p></div>
<div class="afc-card"><span class="afc-card__no">06</span><p>アクセス権限</p></div>
<div class="afc-card"><span class="afc-card__no">07</span><p>レポート出力</p></div>
<div class="afc-card"><span class="afc-card__no">08</span><p>APIキー管理</p></div>
</div>
</div>
</div>
【CSS】
/* 全体:カードグリッドの折返しをコンテナ幅トグルで実演 */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: "Hiragino Sans", system-ui, sans-serif;
background: #f4f6fb;
color: #1b2233;
min-height: 100vh;
display: flex; align-items: center; justify-content: center;
padding: 20px;
}
/* ルート:width:100% が無いと親の flex 中央寄せで潰れ、auto-fit の列計算も崩れるため必須 */
.afc { width: 100%; max-width: 920px; }
.afc__toolbar {
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
margin-bottom: 16px;
}
.afc__label { font-size: 12px; font-weight: 800; color: #5b6478; }
.afc__btns { display: flex; gap: 6px; }
.afc__btns button {
font-size: 12.5px; font-weight: 700; padding: 7px 14px; border-radius: 999px;
border: 1px solid #d8dee9; background: #fff; color: #47506b; cursor: pointer;
transition: background .15s, color .15s, border-color .15s;
}
.afc__btns button:hover { background: #eef2ff; }
.afc__btns button.is-active { background: #4338ca; border-color: #4338ca; color: #fff; }
.afc__stage {
border: 1px dashed #c7cfdf; border-radius: 16px; padding: 20px;
display: flex; justify-content: center; overflow: hidden;
}
/* 列数はここで自動計算される:コンテナ幅 ÷ minmax の下限で決まる */
.afc__grid {
width: var(--afc-w, 290px); /* 初期値は「中」ボタンと一致させる(既定選択との齟齬を防ぐ) */
max-width: 100%;
display: grid;
/* カード下限を 110px と小さめにして、狭いプレビュー(一覧カード約393px幅)でも 1→2→3 列の変化が出せるようにする */
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
gap: 14px;
transition: width .3s ease;
}
.afc-card {
background: #fff; border: 1px solid #e6eaf2; border-radius: 12px;
padding: 18px 14px; display: flex; flex-direction: column; gap: 8px;
box-shadow: 0 10px 24px -18px rgba(15, 23, 42, .4);
}
.afc-card__no { font-size: 11px; font-weight: 800; letter-spacing: .1em; color: #a5adc0; }
.afc-card p { font-size: 13.5px; font-weight: 700; color: #262d3f; }
@media (prefers-reduced-motion: reduce) {
.afc__grid { transition: none; }
.afc__btns button { transition: none; }
}
【JavaScript】
// コンテナ幅トグル:ボタンでグリッドの幅を変え、auto-fit の折返しを実演(null安全)
(() => {
const grid = document.getElementById('afcGrid');
const root = document.getElementById('afcRoot');
if (!grid || !root) return;
// 各段でグリッドの列数が確実に変わる幅にする:狭い=1列 / 中=2列 / 広い=コンテナ一杯(3列以上)。
// 親より広い値は max-width:100% でコンテナ幅に丸められ「中」と「広い」が同化するため、狭い一覧カード
// (グリッド領域 約393px)でも収まる 170/290px にする。minmax(110px) と組で 170→1列・290→2列・100%→3列。
const widths = { narrow: '170px', medium: '290px', wide: '100%' };
const buttons = root.querySelectorAll('[data-width]');
if (!buttons.length) return;
buttons.forEach((btn) => {
btn.addEventListener('click', () => {
const key = btn.getAttribute('data-width');
const w = widths[key] || widths.medium;
grid.style.setProperty('--afc-w', w);
buttons.forEach((b) => b.classList.remove('is-active'));
btn.classList.add('is-active');
});
});
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。