皆さんこんにちは。株式会社ファストコーディングのWebディレクタ 働くおかんです。今回は直近の私のプロジェクトで活用したBento Boxレイアウトというデザイン手法をコーディングする側の観点でお伝えします。このレイアウトをつかうとごちゃごちゃした情報をまとめやすくなるので、使えばきっと提案力がアップすること間違いなしです。
今のデザインの不満とBento Boxの登場
ウェブ制作では、よくクライアントから「シンプルで見やすいデザインにしてほしい」とのリクエストを受けます。ただ、だいたいシンプルじゃないページ=情報量が多いページなんですね。情報量が増えると、どうしても単にガイドライン通りでは限界があります。そこで頼りになるのがBento Boxレイアウトです。このレイアウトの素晴らしいところは、シンプルなのに視覚的に情報を整理しやすくし、ユーザー体験を向上させることができるところです。
Bento Boxで情報整理
ポイントは、情報の整理と視覚的なわかりやすさ。Bento Boxレイアウトとは、お弁当箱のように、スペースを効率的に活用して情報を分ける方法です。異なる情報が混在するページでも、それぞれの要素をボックスに収めることで、スッキリと見せることができます。これにより、情報が頭に入りやすくなります。
実際にどのように実装するのかを5つぐらいにまとめてみました。
実践!Bento Boxの実装例
パターン1:素のCSS Gridで作る基本のBento(最小構成)
<section class="bento bento--basic">
<article class="card card--wide">A</article>
<article class="card">B</article>
<article class="card card--tall">C</article>
<article class="card">D</article>
<article class="card card--wide">E</article>
<article class="card">F</article>
</section>
<style>
.bento {
--gap: clamp(8px, 1vw, 16px);
--col: clamp(160px, 24vw, 300px);
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--col), 1fr));
gap: var(--gap);
grid-auto-flow: dense; /* 空きを詰める */
}
.card {
background: #fff;
border: 1px solid #e7e7e7;
border-radius: 12px;
padding: 16px;
box-shadow: 0 1px 2px rgba(0,0,0,.04);
min-height: 120px;
}
.card--wide { grid-column: span 2; }
.card--tall { grid-row: span 2; min-height: 260px; }
@media (max-width: 640px) {
.card--wide { grid-column: span 1; }
}
</style>
実装ポイント
repeat(auto-fill, minmax())
で列数の自動調整。- “飛び地感”を抑えるため
grid-auto-flow: dense
。 - スパン指定は重要要素に限定(読み順が崩れないよう注意)。
パターン2:アスペクト比とobject-fit
でビジュアル重視(画像中心)
ヒーロー的なカードを混ぜつつ、画像の見え方を一定に保つ版です。aspect-ratio
とobject-fit: cover
でサムネの統一感を出しつつ、テキストは行数クランプでリズムを整えます。
<section class="bento bento--visual">
<article class="vcard vcard--hero">
<img src="/img/hero.jpg" alt="特集" class="vcard__img">
<h3 class="vcard__title">特集:ケーススタディ</h3>
</article>
<article class="vcard"><img src="/img/a.jpg" alt=""><h4>導入事例A</h4></article>
<article class="vcard"><img src="/img/b.jpg" alt=""><h4>導入事例B</h4></article>
<article class="vcard vcard--wide"><img src="/img/c.jpg" alt=""><h4>特集C</h4></article>
<article class="vcard"><img src="/img/d.jpg" alt=""><h4>Tips</h4></article>
</section>
<style>
.bento--visual { --gap: 12px; --col: clamp(180px, 26vw, 320px);
display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--col),1fr));gap:var(--gap);grid-auto-flow:dense;}
.vcard{border:1px solid #eee;border-radius:14px;overflow:hidden;background:#fff}
.vcard__img, .vcard img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block}
.vcard h3,.vcard h4{margin:.6em .9em 1em;font-size:clamp(14px,1.6vw,18px);line-height:1.5}
.vcard--hero{grid-column:span 2}
.vcard--wide{grid-column:span 2}
@media (max-width: 700px){.vcard--hero,.vcard--wide{grid-column:span 1}}
</style>
実装のポイント
aspect-ratio
で枠の安定→CLS回避。- 文字は
clamp()
で最小~最大を縛り、行数クランプを併用して整列。
パターン3:Bootstrap 5ユーティリティで作るBento(設計コスト低)
デザインガイドラインが決まっている現場ではBootstrap 5で手早く。row
×col
とユーティリティクラスで余白・角丸・影を統一し、必要な所だけgrid
を併用します。
コード(CDN併用)
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<section class="container py-4">
<div class="row g-3 align-items-stretch">
<div class="col-12 col-md-6">
<div class="card h-100 shadow-sm rounded-4 p-3">A(ワイド)</div>
</div>
<div class="col-6 col-md-3">
<div class="card h-100 shadow-sm rounded-4 p-3">B</div>
</div>
<div class="col-6 col-md-3">
<div class="card h-100 shadow-sm rounded-4 p-3">C</div>
</div>
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm rounded-4 p-3">D(やや大)</div>
</div>
<div class="col-6 col-md-4">
<div class="card h-100 shadow-sm rounded-4 p-3">E</div>
</div>
<div class="col-6 col-md-4">
<div class="card h-100 shadow-sm rounded-4 p-3">F</div>
</div>
</div>
</section>
実装のポイント
align-items-stretch
で等高化、g-3
で余白統一。- レスポンシブは
col-
で幅の比率を素早く調整。 - さらに“詰めたい”場合は
.row
内のカードを内側Gridで調整可能。
パターン4:MixItUpで“動くBento”(フィルタ・ソート)
カードをカテゴリーや人気順で切り替えたい時は、軽量のMixItUpを組み合わせます。Bentoのまとまりは維持しつつ、並べ替え・絞り込みで提案の切り口を増やせます。
コード(最小構成)
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/mixitup@3/dist/mixitup.min.js"></script>
<section class="container py-4">
<div class="d-flex gap-2 mb-3">
<button class="btn btn-outline-primary" data-filter="all">すべて</button>
<button class="btn btn-outline-primary" data-filter=".case">事例</button>
<button class="btn btn-outline-primary" data-filter=".tips">Tips</button>
<button class="btn btn-outline-primary" data-sort="default:asc">標準</button>
<button class="btn btn-outline-primary" data-sort="data-pop:desc">人気順</button>
</div>
<div id="mix" class="row g-3 align-items-stretch">
<div class="col-12 col-md-6 mix case" data-pop="5">
<div class="card h-100 rounded-4 p-3">A(事例/pop:5)</div>
</div>
<div class="col-6 col-md-3 mix tips" data-pop="1">
<div class="card h-100 rounded-4 p-3">B(Tips/pop:1)</div>
</div>
<div class="col-6 col-md-3 mix case" data-pop="3">
<div class="card h-100 rounded-4 p-3">C(事例/pop:3)</div>
</div>
<div class="col-12 col-md-4 mix tips" data-pop="8">
<div class="card h-100 rounded-4 p-3">D(Tips/pop:8)</div>
</div>
<div class="col-6 col-md-4 mix case" data-pop="6">
<div class="card h-100 rounded-4 p-3">E(事例/pop:6)</div>
</div>
<div class="col-6 col-md-4 mix tips" data-pop="2">
<div class="card h-100 rounded-4 p-3">F(Tips/pop:2)</div>
</div>
</div>
</section>
<script>
const mixer = mixitup('#mix', {
selectors: { target: '.mix' },
animation: { duration: 300, nudge: true, clampWidth: true }
});
document.querySelectorAll('[data-filter]').forEach(btn => {
btn.addEventListener('click', () => mixer.filter(btn.dataset.filter));
});
document.querySelectorAll('[data-sort]').forEach(btn => {
btn.addEventListener('click', () => mixer.sort(btn.dataset.sort));
});
</script>
実装のポイント
.mix
にカテゴリー用クラス、並び替え指標はdata-*
で付与。- レイアウトはBootstrapのグリッド比率で調整し、MixItUpで順序だけ変える。
パターン5:情報量に応じて“伸びるカード”(CSS Grid × grid-auto-rows
)
テキスト量に差があると高さが揃わずノイズになります。grid-auto-rows
+行高ユニットを使うと、テキストに合わせて自然に伸びるBentoが作れます。
<section class="bento bento--elastic">
<article class="e-card"><h4>お知らせ</h4><p>短い文</p></article>
<article class="e-card"><h4>導入事例</h4><p>本文がやや長い場合の例。本文がやや長い場合の例。</p></article>
<article class="e-card e-card--wide"><h4>特集</h4><p>長文でも自動で伸びます。長文でも自動で伸びます。長文でも自動で伸びます。</p></article>
<article class="e-card"><h4>Tips</h4><p>短文</p></article>
</section>
<style>
.bento--elastic{
--gap:12px; --col: clamp(180px, 26vw, 320px);
display:grid; gap:var(--gap);
grid-template-columns:repeat(auto-fill,minmax(var(--col),1fr));
grid-auto-rows: 8px; /* 1行の“基準” */
}
.e-card{border:1px solid #e8e8e8;border-radius:12px;padding:16px;background:#fff;
display:grid;grid-auto-rows:min-content;align-content:start}
.e-card h4{margin:0 0 .5em;font-size:clamp(14px,1.6vw,18px)}
.e-card--wide{grid-column:span 2}
@media (max-width: 700px){.e-card--wide{grid-column:span 1}}
</style>
実装のポイント
- 行高を
grid-auto-rows
で基準化し、カードは内容に応じて伸縮。 - 画像混在の場合は、テキスト領域を
display:grid
にして見出し→本文の流れを固定。
実際にあった活用方法
ある小売業のお客様が商品の一覧ページを見やすくしてほしいと頼んできました。そこでBento Boxレイアウトを提案し実装したところ、ユーザーが商品を直感的に比較できるようになり、購入意欲を高めたと評価をいただきました。お客様からは、問い合わせの減少やサイト滞在時間の向上の報告もあり、とても効果があったと実感しています。
まとめ – Bento Boxレイアウトで提案力を磨こう
Bento Boxレイアウトは、Webディレクターやプロジェクトマネージャーにとって非常に役立つ提案のネタです。ぜひ次のプロジェクトで試してみてください。興味があれば、株式会社ファストコーディングでの作成や改善サポートも承っておりますので、 こちらからぜひご連絡ください。