CSS flexboxで要素を中央寄せする5つのパターン

flexboxを使った中央寄せは、水平・垂直・両方向など複数の方法があります。この記事では、実務でよく使う5つのパターンと、各パターンの使い分けを、すぐに仕事で活用できる実装例とともに解説します。

flexboxで中央寄せができる理由

flexboxは、CSSの柔軟なボックスレイアウトモデルです。親要素にdisplay: flexを指定すると、子要素の配置を簡単に制御できるようになります。従来のfloatやpositionを使った中央寄せよりも、コードがシンプルで保守性に優れています。

flexboxが対応ブラウザ(IE11以降、およびすべてのモダンブラウザ)で標準化されてから、Webデザインの実装方法が大きく変わりました。現在では、ほぼすべてのプロジェクトで採用できます。

水平方向のみ中央寄せ

子要素を水平方向(左右)にのみ中央寄せしたい場合、justify-content: centerを使います。これが最もシンプルで使用頻度の高いパターンです。

<!-- HTML例 -->
<div class="container">
  <p>このテキストは水平方向に中央寄せされます</p>
</div>
/* CSS */
.container {
  display: flex;
  justify-content: center; /* 水平方向の中央寄せ */
  height: 100px;
  border: 1px solid #ccc;
}

justify-contentプロパティは、flexboxの主軸(初期値は水平方向)に沿って要素を配置します。center以外にもflex-start(左寄せ)、flex-end(右寄せ)、space-between(均等分散)などの値が使用できます。

垂直方向のみ中央寄せ

子要素を垂直方向(上下)にのみ中央寄せする場合は、align-items: centerを使います。垂直中央のみが必要なケースは、ナビゲーションバーのアイコンやボタンなどで頻出です。

<!-- HTML例 -->
<header class="navbar">
  <img src="logo.png" alt="ロゴ" class="logo">
  <nav class="nav-menu">メニュー</nav>
</header>
/* CSS */
.navbar {
  display: flex;
  align-items: center; /* 垂直方向の中央寄せ */
  height: 60px;
  background-color: #333;
}

.logo {
  width: 40px;
  margin-right: 20px;
}

垂直方向の中央寄せにはalign-itemsを使う点が重要です。justify-contentと混同しやすいため、「主軸がjustify、交差軸がalign」と覚えると区別できます。

水平・垂直両方向の中央寄せ

最も実用的なのは、水平・垂直の両方向に中央寄せするパターンです。モーダルダイアログやエラーメッセージなど、デザインの中心に要素を配置したい場合に使用します。

<!-- HTML例 -->
<div class="modal-overlay">
  <div class="modal-content">
    <h2>確認ダイアログ</h2>
    <p>こちらの操作を実行してよろしいですか?</p>
    <button>キャンセル</button>
    <button>実行</button>
  </div>
</div>
/* CSS */
.modal-overlay {
  display: flex;
  justify-content: center; /* 水平中央 */
  align-items: center;     /* 垂直中央 */
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal-content {
  background-color: white;
  padding: 30px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  max-width: 400px;
}

このパターンでは、justify-contentalign-itemsの両方をcenterに設定します。これにより、親要素のサイズに関わらず、子要素が完全に中央に配置されます。

複数の子要素を中央寄せ

複数要素を一列で中央配置

複数の要素がある場合、justify-content: centerを使うと全体が中央に配置されます。要素間のスペースは自動的に調整されます。

<!-- HTML例 -->
<div class="button-group">
  <button class="btn">キャンセル</button>
  <button class="btn btn-primary">送信</button>
  <button class="btn">リセット</button>
</div>
/* CSS */
.button-group {
  display: flex;
  justify-content: center; /* 複数要素を中央に配置 */
  gap: 10px; /* 要素間のスペース */
  padding: 20px;
}

.btn {
  padding: 10px 20px;
  border: 1px solid #ccc;
  background-color: #f5f5f5;
  cursor: pointer;
  border-radius: 4px;
}

.btn-primary {
  background-color: #007bff;
  color: white;
  border-color: #007bff;
}

gapプロパティを使うと、要素間の余白を簡潔に指定できます。従来のmarginを使った方法より、保守性が高いです。

複数要素を中央で行折り返し

ウィンドウサイズが小さい場合に要素を折り返したい場合は、flex-wrap: wrapを追加して、justify-content: centerと組み合わせます。

<!-- HTML例 -->
<div class="product-grid">
  <div class="product-card">商品1</div>
  <div class="product-card">商品2</div>
  <div class="product-card">商品3</div>
  <div class="product-card">商品4</div>
</div>
/* CSS */
.product-grid {
  display: flex;
  justify-content: center; /* 各行を中央に */
  flex-wrap: wrap;         /* 折り返しを許可 */
  gap: 20px;
  padding: 20px;
}

.product-card {
  width: 150px;
  height: 150px;
  background-color: #e9ecef;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
}

この方法は、レスポンシブデザインで複数列のレイアウトを実装する際に便利です。メディアクエリと組み合わせることで、デバイスサイズに応じた柔軟なレイアウトが実現できます。

flexboxとGridの使い分け

中央寄せだけならflexboxで十分ですが、複雑な2次元レイアウトが必要な場合はCSS Gridの方が適切です。flexboxは1次元(行または列)、Gridは2次元(行と列の両方)のレイアウトに特化しています。

実務での判断基準は「1行または1列で配置するならflexbox、複数行・複数列の複雑な配置ならGrid」です。

よくあるハマりポイント

親要素の高さが指定されていない

垂直中央寄せを使う際、親要素の高さ(height)が自動(auto)のままでは、期待した結果が得られません。必ず明示的に高さを指定してください。

/* ❌ うまく機能しない */
.container {
  display: flex;
  align-items: center; /* 高さがないため無意味 */
}

/* ✅ 正しい実装 */
.container {
  display: flex;
  align-items: center;
  height: 200px; /* 高さを明示的に指定 */
}

子要素のwidthが指定されていない

水平中央寄せの場合、子要素の幅が親要素いっぱいに広がっていると、中央寄せの効果が見えません。子要素に適切な幅を指定するか、flex-shrink: 0を追加してください。

/* ❌ 中央寄せが見えない */
.parent {
  display: flex;
  justify-content: center;
}

.child {
  /* widthが指定されていない */
}

/* ✅ 正しい実装 */
.parent {
  display: flex;
  justify-content: center;
}

.child {
  width: fit-content; /* 内容に合わせたサイズ */
}

IEとの互換性

IE11はflexboxをサポートしていますが、いくつかのバグがあります。もしIE11対応が必要な場合は、テスト環境で念入りにチェックしてください。現在はほぼすべてのプロジェクトでIE対応は不要ですが、レガシーシステムの場合は注意が必要です。

パフォーマンス上の注意点

flexboxは計算量が多いため、多数の子要素(数千以上)がある場合、レンダリング性能に影響する可能性があります。そのような場合は、virtual scrollingライブラリの使用を検討してください。ただし、通常のWebサイトでは問題になりません。

実装チェックリスト

  • 親要素にdisplay: flexを指定している
  • 水平中央寄せにjustify-content: centerを使用している
  • 垂直中央寄せにalign-items: centerを使用している
  • 垂直中央寄せの場合、親要素の高さが指定されている
  • 複数要素の場合、gapプロパティでスペースを管理している
  • レスポンシブデザイン対応が必要な場合、flex-wrap: wrapを検討している

よくある質問

A: flexboxが登場する前は、margin: autoposition: absoluteを組み合わせて中央寄せを実装していました。flexboxの方がコードが簡潔で、親要素の制約が少ないため、現在はflexboxが推奨されています。ただし、margin: autoも正しく理解していれば有効な方法です。

A: はい、justify-contentflex-end(右寄せ)やflex-start(左寄せ)を指定できます。また、justify-content: space-betweenを使うと、要素を両端に配置してスペースを均等に分散できます。

K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →