【CSS】FlexboxとCSS Grid Layoutの基本と使い分け

CSS GridはモダンWEBレイアウト

WEBサイトのCSSレイアウトで「思うように要素が配置できない…」と悩んでいませんか?
FlexboxCSS Grid Layoutという非常に強力で柔軟なレイアウトモジュールがあります!これらを使いこなせれば、複雑なレイアウトも直感的に、そして簡単に実現できるようになります。
この記事では、FlexboxとCSS Grid Layoutの基本的な使い方と、それぞれの得意なこと、そして具体的な使い分けについて、サンプルコードをたくさん交えながら分かりやすく解説していきます。

1. Flexboxとは? - 1次元レイアウトに最適

Flexbox(Flexible Box Layout Module)は、主に1次元(1行 または1 列)のレイアウトを扱うのに適したモジュールです。中の要素(アイテム)のサイズや間隔を、親要素(コンテナ)のスペースに合わせて柔軟に調整してくれます。

主な用途

  • ナビゲーションメニュー
  • ボタンの横並び
  • カード内の要素配置
  • 要素の垂直・水平方向の中央揃え

Flexboxの基本構造

Flexboxを使うには、まず親要素(コンテナ)に display: flex; を指定します。

<div class="flex-container">
  <div class="flex-item">アイテム1</div>
  <div class="flex-item">アイテム2</div>
  <div class="flex-item">アイテム3</div>
</div>
.flex-container {
  display: flex; /* これでFlexboxが有効になる */
  border: 2px solid blue; /* コンテナの範囲を分かりやすくするため */
  padding: 10px;
}

.flex-item {
  background-color: lightblue;
  border: 1px solid navy;
  padding: 20px;
  margin: 5px; /* アイテム間の隙間 */
  text-align: center;
}

この時点で、子要素(アイテム)が横並びになります。これがFlexboxのデフォルトの挙動です。

アイテム1
アイテム2
アイテム3

親要素(コンテナ)に指定する主なプロパティ

  1. flex-direction:アイテムの並ぶ方向を指定します。
    • row(デフォルト): 左から右へ横並び
    • row-reverse:右から左へ横並び
    • column:上から下へ縦並び
    • column-reverse:下から上へ縦並び
.flex-container {
  display: flex;
  flex-direction: row; /* 横並び (デフォルト) */
  /* flex-direction: column; */ /* 縦並びにしたい場合 */
  border: 2px solid blue;
  padding: 10px;
  height: 200px; /* 縦並びの際に分かりやすくするため高さを指定 */
}
/* (flex-itemのスタイルは省略) */
  1. justify-content:主軸方向(flex-directionで指定した方向)の揃え方を指定します。
    • flex-start(デフォルト): 開始位置に寄せる
    • flex-end:終了位置に寄せる
    • center:中央に寄せる
    • space-between:最初と最後のアイテムを両端に配置し、残りを均等間隔で配置
    • space-around:各アイテムの周りに均等なスペースを配置(両端は半分のスペース)
    • space-evenly:すべてのアイテム間と両端に均等なスペースを配置
/* 例: アイテムを中央揃えにする */
.flex-container {
  display: flex;
  justify-content: center; /* 主軸方向(デフォルトは横)の中央揃え */
  border: 2px solid blue;
  padding: 10px;
}
/* (flex-itemのスタイルは省略) */
/* 例: アイテムを均等間隔で配置する */
.flex-container {
  display: flex;
  justify-content: space-between; /* 両端に寄せ、間を均等に */
  border: 2px solid blue;
  padding: 10px;
}
/* (flex-itemのスタイルは省略) */
  1. align-items:交差軸方向(主軸と垂直な方向)の揃え方を指定します。
    • stretch(デフォルト):アイテムをコンテナの高さ(または幅)いっぱいに伸ばす
    • flex-start:開始位置に寄せる
    • flex-end:終了位置に寄せる
    • center:中央に寄せる
    • baseline:アイテム内のテキストのベースラインで揃える
/* 例: アイテムを垂直方向の中央に揃える */
.flex-container {
  display: flex;
  align-items: center; /* 交差軸方向(デフォルトは縦)の中央揃え */
  border: 2px solid blue;
  padding: 10px;
  height: 150px; /* 高さを指定しないと効果が分かりにくい */
}
/* (flex-itemのスタイルは省略) */
  1. flex-wrap:アイテムがコンテナに収まらない場合の折り返しを指定します。
    • nowrap (デフォルト): 折り返さない(はみ出す)
    • wrap:折り返す
    • wrap-reverse:逆方向に折り返す
.flex-container {
  display: flex;
  flex-wrap: wrap; /* はみ出たら折り返す */
  border: 2px solid blue;
  padding: 10px;
  width: 300px; /* 幅を制限して折り返しを発生させる */
}

.flex-item {
  background-color: lightblue;
  border: 1px solid navy;
  padding: 20px;
  margin: 5px;
  width: 100px; /* アイテムの幅を指定 */
  text-align: center;
}

子要素(アイテム)に指定する主なプロパティ

  1. flex-grow:コンテナ内の余白に対して、アイテムがどれだけ伸びるかの比率を指定します。(デフォルト: 0)
.flex-item:nth-child(1) {
  flex-grow: 1; /* 他のアイテムより1倍伸びる */
}
.flex-item:nth-child(2) {
  flex-grow: 2; /* 他のアイテムより2倍伸びる */
}
/* アイテム3はデフォルトのflex-grow: 0 */

この場合、余ったスペースを 1:2:0 の比率でアイテム1とアイテム2に分配します。

2. flex-shrink:コンテナのスペースが足りない場合に、アイテムがどれだけ縮むかの比率を指定します。(デフォルト:1) 値が大きいほど縮みやすくなります。

3. flex-basis:アイテムの基本サイズを指定します。width や height より優先されることがあります。

4. order:アイテムの表示順序を数値で指定します。(デフォルト:0) 数値が小さいほど前に表示されます。

.flex-item:nth-child(1) { order: 3; }
.flex-item:nth-child(2) { order: 1; }
.flex-item:nth-child(3) { order: 2; }
/* 表示順: アイテム2 -> アイテム3 -> アイテム1 */

2. CSS Grid Layoutとは? - 2次元レイアウトの魔法

CSS Grid Layout(または単にGrid)は、2次元(行 と 列)のレイアウトを扱うためのモジュールです。Webページ全体のレイアウトや、複雑なコンポーネントの配置など、行と列で構成されるグリッド状のレイアウトを作成するのに非常に強力です。

主な用途

  • Webページ全体のレイアウト(ヘッダー、サイドバー、メインコンテンツ、フッターなど)
  • カードや画像のグリッド表示
  • 複雑なフォームのレイアウト

Gridの基本構造

Gridを使うには、親要素(コンテナ)に display: grid;を指定し、grid-template-columns や grid-template-rows で行と列の構成を定義します。

<div class="grid-container">
  <div class="grid-item">アイテム1</div>
  <div class="grid-item">アイテム2</div>
  <div class="grid-item">アイテム3</div>
  <div class="grid-item">アイテム4</div>
  <div class="grid-item">アイテム5</div>
  <div class="grid-item">アイテム6</div>
</div>
.grid-container {
  display: grid; /* これでGridが有効になる */
  /* 例: 3つの均等な幅の列を作成 */
  grid-template-columns: 1fr 1fr 1fr; /* fr は利用可能なスペースの割合を示す単位 */
  /* 例: 2つの行を作成 (高さは自動) */
  grid-template-rows: auto auto;
  gap: 10px; /* グリッド線(アイテム間)の隙間 */
  border: 2px solid green; /* コンテナの範囲を分かりやすくするため */
  padding: 10px;
}

.grid-item {
  background-color: lightgreen;
  border: 1px solid darkgreen;
  padding: 20px;
  text-align: center;
}

これで、3列×2行のグリッドレイアウトが作成され、アイテムが順番に配置されます。

アイテム1
アイテム2
アイテム3
アイテム4
アイテム5
アイテム6

親要素(コンテナ)に指定する主なプロパティ

  1. grid-template-columns:列の幅や数を定義します。
    • ピクセル値:100px 200px 100px(3列、それぞれの幅を指定)
    • パーセンテージ:25% 50% 25%
    • auto:コンテンツに応じた幅
    • fr単位:利用可能なスペースの割合(1fr 2fr 1fr -> スペースを1:2:1で分割)
    • repeat()関数:repeat(3, 1fr) (1frの列を3つ作成)
.grid-container {
  display: grid;
  /* 1列目は100px, 2列目は残りスペースの1/3, 3列目は残りスペースの2/3 */
  grid-template-columns: 100px 1fr 2fr;
  gap: 10px;
  border: 2px solid green;
  padding: 10px;
}
/* (grid-itemのスタイルは省略) */
  1. grid-template-rows:行の高さを定義します。使い方は grid-template-columns と同様です。
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* 1行目は50px, 2行目は100px */
  grid-template-rows: 50px 100px;
  gap: 10px;
  border: 2px solid green;
  padding: 10px;
}
/* (grid-itemのスタイルは省略) */
  1. gap(または grid-gap):グリッドアイテム間の隙間(溝)を指定します。
    • gap: 10px;(行間、列間ともに10px)
    • gap: 20px 10px;(行間20px、列間10px)
    • row-gap: 20px;(行間のみ)
    • column-gap: 10px; (列間のみ)
  2. justify-items:グリッドセル内のアイテムを水平方向にどう配置するか指定します。(コンテナ全体で指定)
    • start, end, center, stretch (デフォルト)
  3. align-items:グリッドセル内のアイテムを垂直方向にどう配置するか指定します。(コンテナ全体で指定)
    • start, end, center, stretch (デフォルト)
  4. place-items:align-items justify-items を一括で指定します。(例:place-items: center center; や place-items: center;)
  5. justify-content:グリッドコンテナ内のグリッド全体を水平方向にどう配置するか指定します。(グリッド全体の幅がコンテナより狭い場合に効果あり)
    • start, end, center, space-between, space-around, space-evenly
  6. align-content:グリッドコンテナ内のグリッド全体を垂直方向にどう配置するか指定します。(グリッド全体の高さがコンテナより低い場合に効果あり)
    • start, end, center, space-between, space-around, space-evenly
  7. place-content:align-content justify-content を一括で指定します。(例:place-content: center center; や place-content: center;)

子要素(アイテム)に指定する主なプロパティ

Gridの強力な点は、アイテムを特定のグリッド線に基づいて配置できることです。

  • grid-column-start, grid-column-end:アイテムがどの列線からどの列線までを占めるか指定します。
  • grid-row-start, grid-row-end:アイテムがどの行線からどの行線までを占めるか指定します。
  • grid-column:grid-column-start / grid-column-end のショートハンド。
  • grid-row:grid-row-start / grid-row-end のショートハンド。
  • grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end のショートハンド、または名前付きグリッドエリアを使用します。
.grid-container {
  display: grid;
  grid-template-columns: repeat(4, 1fr); /* 4列 */
  grid-template-rows: auto auto auto;   /* 3行 */
  gap: 10px;
  border: 2px solid green;
  padding: 10px;
  height: 300px; /* 高さを指定 */
}

.grid-item {
  background-color: lightgreen;
  border: 1px solid darkgreen;
  padding: 10px; /* パディングを少し減らす */
  text-align: center;
  font-size: 0.9em; /* 文字サイズを少し小さく */
}

/* アイテム1を、1列目から3列目まで広げる */
.grid-item:nth-child(1) {
  grid-column-start: 1;
  grid-column-end: 3; /* 3番目の線の手前まで */
  /* ショートハンド: grid-column: 1 / 3; */
  background-color: #a0e0a0; /* 色を変えて目立たせる */
}

/* アイテム3を、2行目から4行目まで広げる */
.grid-item:nth-child(3) {
  grid-row-start: 2;
  grid-row-end: 4; /* 4番目の線の手前まで */
  /* ショートハンド: grid-row: 2 / 4; */
  background-color: #7fbf7f; /* 色を変えて目立たせる */
}

/* アイテム5を、3列目の2行目に配置 */
.grid-item:nth-child(5) {
  grid-column: 3 / 4; /* 3列目 */
  grid-row: 2 / 3;    /* 2行目 */
  background-color: #5dab5d; /* 色を変えて目立たせる */
}

(HTMLはアイテム数を適宜増やして試してみてください)

span キーワードを使うと、「何マス分」という指定も可能です。

/* アイテム2を、開始位置から2列分広げる */
.grid-item:nth-child(2) {
  grid-column: span 2;
}

Flexbox vs. Grid: いつ、どちらを使うべきか?

これが一番の疑問点かもしれませんね。基本的な考え方は以下の通りです。

  • Flexbox
    • 1次元レイアウト(行 または 列 のどちらか一方)が得意。
    • コンテンツの量に応じてアイテムのサイズや間隔を柔軟に調整したい場合。
    • ナビゲーション、ボタンの並び、要素の簡単な中央揃えなど、コンポーネント内部のレイアウトに向いている。
    • コンテンツ主導のレイアウト(コンテンツのサイズがレイアウトに影響を与える)。
  • CSS Grid
    • 2次元レイアウト(行 と 列 の両方)が得意。
    • 行と列で構成される厳密なグリッド構造を作りたい場合。
    • ページ全体のレイアウト(ヘッダー、フッター、サイドバーなど)、複雑な要素配置に向いている。
    • レイアウト主導のレイアウト(先にグリッド構造を定義し、そこにコンテンツを配置する)。

簡単な使い分けの目安

目的・箇所推奨理由
ナビゲーションメニューの項目並びFlexbox基本的に横一列 or 縦一列で、間隔調整が主目的。
ページ全体の骨組みGridヘッダー、サイドバー、メイン、フッターなど2次元配置が明確。
カード型コンテンツのリストGrid複数列・複数行の整然としたグリッド表示に適している。
カード内の要素(画像、テキスト)Flexboxカードというコンポーネント内部の要素配置(1次元が多い)。
ボタンの横並びFlexbox横一列に並べて間隔を調整するのが容易。
とにかく要素を中央揃えしたいFlexboxjustify-content: center; align-items: center; で簡単に実現できる。
フォーム要素のラベルと入力欄配置Gridラベルと入力欄を整列させる2次元レイアウトに適している場合がある

FlexboxとGridの組み合わせ

FlexboxとGridは、どちらか一方しか使えないわけではありません。むしろ、組み合わせて使うことで、より複雑で洗練されたレイアウトを実現できます。

例えば、

  1. ページ全体の大きな枠組みをGridで作成する(ヘッダー、メイン、サイドバー、フッターなど)。
  2. そのグリッドアイテム(例:ヘッダー)の中で、ロゴとナビゲーションメニューを横並びにするためにFlexboxを使う。
  3. メインコンテンツエリア(グリッドアイテム)の中で、記事カードを複数列表示するためにGridを使う。
  4. 個々の記事カード(グリッドアイテム)の中で、サムネイル画像とテキストを配置するためにFlexboxを使う。

このように、それぞれの得意な役割分担で使い分けるのが効果的です。

<div class="page-container">
  <header class="page-header">
    <div class="logo">ロゴ</div>
    <nav class="main-nav">
      <a href="#">メニュー1</a>
      <a href="#">メニュー2</a>
      <a href="#">メニュー3</a>
    </nav>
  </header>
  <main class="page-main">メインコンテンツ...</main>
  <aside class="page-sidebar">サイドバー...</aside>
  <footer class="page-footer">フッター...</footer>
</div>
/* ページ全体のGrid設定 */
.page-container {
  display: grid;
  grid-template-columns: 1fr 250px; /* メイン:残り全部, サイドバー:250px */
  grid-template-rows: auto 1fr auto; /* ヘッダー:自動, メイン/サイド:残り, フッター:自動 */
  grid-template-areas:
    "header header"
    "main sidebar"
    "footer footer";
  min-height: 100vh; /* 画面の高さいっぱいにする */
  gap: 15px;
}

.page-header { grid-area: header; background-color: #eee; padding: 10px; }
.page-main { grid-area: main; background-color: #f9f9f9; padding: 20px; }
.page-sidebar { grid-area: sidebar; background-color: #eef; padding: 15px; }
.page-footer { grid-area: footer; background-color: #ddd; padding: 10px; text-align: center;}

/* ヘッダー内部のFlexbox設定 */
.page-header {
  display: flex;
  justify-content: space-between; /* 両端揃え */
  align-items: center;       /* 垂直中央揃え */
}

.main-nav a {
  margin-left: 15px; /* メニュー間のスペース */
  text-decoration: none;
  color: blue;
}

/* (ロゴのスタイルは省略) */
ロゴ
メインコンテンツ...
フッター...

まとめ

FlexboxとCSS Grid Layoutは、現代のWebレイアウトに欠かせない強力なツールです。

  • Flexbox1次元のレイアウト、特にコンテンツの柔軟な配置や間隔調整が得意。
  • CSS Grid2次元のレイアウト、行と列からなる厳密なグリッド構造の作成が得意。

どちらが優れているというわけではなく、適材適所で使い分けること、そして必要に応じて組み合わせて使うことが重要です。

最初は少し難しく感じるかもしれませんが、実際にコードを書いて、ブラウザの開発者ツールなどで表示を確認しながら試してみるのが一番の近道です。たくさんのサンプルコードを参考に、ぜひFlexboxとGridをマスターして、快適なCSSレイアウトを実現してください!

PR広告