カードを指定した列数で並べて表示するFlexboxの使い方

Flexbox

Flexboxを使って、複数のカードを指定した列数で均等に並べる方法を紹介します。カードの横幅を調整することで、3列や4列など、決められた列数で配置できます。カードが1行に収まらない場合は、次の行へ自動的に折り返されます。

今回のデモでは、5枚のカードを3列で配置し、4枚目と5枚目を次の行に表示します。カード同士には20pxの間隔を設け、画面幅が640px以下になると2列に切り替わります。スマートフォンではカードの高さと間隔も調整し、画面幅に合わせて表示します。

列数を指定する場合は、カードの横幅だけでなく、カード同士の間隔も考慮する必要があります。今回のようにgapを使用する場合は、calc()で間隔分を差し引いてから列数で割ることで、各行のカードを均等な幅に揃えられます。HTMLとCSSだけで実装でき、JavaScriptは必要ありません。

デモ

5枚のカードを3列で配置し、4枚目以降は次の行に折り返します。カード同士の間隔は20pxです。画面幅が640px以下になると2列に切り替わり、カードの間隔は16pxになります。

コードをコピーして使おう!

<!DOCTYPE html>
<html lang="ja">
<head>
  <!-- 文字コードの設定 -->
  <meta charset="UTF-8">
  <!-- スマートフォンなどの画面幅に対応 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- ページタイトル -->
  <title>カードを指定した列数で並べるFlexbox</title>
  <!-- カードの配置とデザインを設定するCSSを読み込む -->
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <!-- 指定した列数で並べる5枚のカード -->
  <div class="flexbox-column-count_container">
    <div class="flexbox-column-count_card"></div>
    <div class="flexbox-column-count_card"></div>
    <div class="flexbox-column-count_card"></div>
    <div class="flexbox-column-count_card"></div>
    <div class="flexbox-column-count_card"></div>
  </div>

</body>
</html>
コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。 免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
A

Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。

InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。

ファイル構成と設置方法

今回のサンプルは、HTMLとCSSの2つのファイルで構成されています。HTMLでは5枚のカードを親コンテナ内に配置し、CSSではFlexboxによる3列表示、カード同士の間隔、横幅、高さ、背景色を設定しています。画面幅が640px以下になると2列表示へ切り替わります。JavaScriptは使用していません。

sample/
  ├── index.html
  └── style.css

各ファイルの役割
index.htmlには、カード全体を囲む.flexbox-column-count_containerと、5枚の.flexbox-column-count_cardを記述しています。style.cssでは、カードの列数・間隔・サイズ・背景色と、スマートフォン向けの表示設定を行っています。

設置方法・使い方
「サンプル一式をダウンロード」をクリックしてZIPファイルを保存し、展開してください。sampleフォルダ内のindex.htmlとstyle.cssを同じ階層に配置し、index.htmlをブラウザで開くと、5枚のカードが3列で表示されます。
1行目には3枚、2行目には2枚のカードが並びます。画面幅が640px以下になると2列に切り替わり、3行に分かれて表示されます。

Flexboxでカードを折り返す仕組み
style.cssの.flexbox-column-count_containerでは、display: flex;でFlexboxを有効にし、flex-wrap: wrap;でカードの折り返しを許可しています。
カードの列数は、子カードに指定した横幅によって決まります。カード同士の間隔を設けない場合は、親コンテナの横幅を列数で割るだけで均等に配置できます。

gapを使わずに3列・4列・5列で並べる方法
カード同士に間隔を設けない場合は、親コンテナのgapを削除するか、gap: 0;に変更します。
あとは、子カードのwidthに列数を指定するだけです。3列なら3等分、4列なら4等分、5列なら5等分します。

/* 3列:横幅を3等分 */
width: calc(100% / 3);

/* 4列:横幅を4等分 */
width: calc(100% / 4);

/* 5列:横幅を5等分 */
width: calc(100% / 5);

例えば、3列にする場合はwidth: calc(100% / 3);を指定するだけで、カードが横幅の3分の1ずつを使用します。4列なら100% / 4、5列なら100% / 5に変更するだけです。
このように、カード同士の間隔が不要であれば、複雑な計算をする必要はありません。なお、今回のサンプルではカード同士に20pxの間隔を設けているため、次の計算方法を使用しています。

gapを使ってカード同士に間隔を設ける方法
カード同士に間隔を設ける場合は、親コンテナのgapを使用します。今回のサンプルではgap: 20px;を指定し、横方向と縦方向に20pxの間隔を設けています。
gapを使用する場合は、カードの横幅に隙間が加わるため、横幅を計算するときに隙間の合計を差し引く必要があります。

/* =========================================
  カードを指定した列数で配置
========================================= */

.flexbox-column-count_container {
  display: flex; /* Flexboxを有効にする */
  flex-wrap: wrap; /* カードを次の行へ折り返す */
  gap: 20px; /* カード同士の間隔 */
  width: 100%; /* 設置先の横幅に合わせる */
  max-width: 700px; /* カード全体の最大横幅 */
  margin: 40px auto 0; /* 上40px・左右自動・下0の余白 */
  padding: 20px; /* 内側の余白 */
  border: 1px solid #cbd5e1; /* 外枠 */
  background: #ffffff; /* 背景色 */
  box-sizing: border-box; /* 余白と枠線を横幅に含める */
}

gapありの場合の3列・4列・5列のCSS指定一覧
gap: 20px;の場合、3列では隙間が2か所、4列では3か所、5列では4か所になります。
それぞれの隙間の合計を100%から差し引き、残った横幅を列数で割ります。

/* 3列:20px × 2か所 = 40px */
width: calc((100% - 40px) / 3);

/* 4列:20px × 3か所 = 60px */
width: calc((100% - 60px) / 4);

/* 5列:20px × 4か所 = 80px */
width: calc((100% - 80px) / 5);

今回のサンプルでは、width: calc((100% - 40px) / 3);を使用して3列にしています。4列へ変更する場合はwidth: calc((100% - 60px) / 4);、5列へ変更する場合はwidth: calc((100% - 80px) / 5);に書き換えてください。
gap: 20px;を指定したままwidth: calc(100% / 3);にすると、カード3枚の横幅に隙間が加わり、3列に収まらなくなります。gapを使用する場合と使用しない場合で、計算方法が異なる点に注意してください。

カードの横幅・高さ・角丸を調整する方法
style.cssの.flexbox-column-count_cardでは、カードの横幅・高さ・角丸を設定しています。

/* =========================================
  子カード共通:3列
========================================= */

.flexbox-column-count_card {
  width: calc((100% - 40px) / 3); /* 20pxの隙間2か所を引き、残りを3等分する */
  height: 160px; /* カードの高さ */
  flex-shrink: 0; /* カードが縮小されるのを防ぐ */
  border-radius: 8px; /* カードの角丸 */
  box-sizing: border-box; /* 余白と枠線を横幅に含める */
}

height: 160px;を200pxにするとカードが縦長になり、100pxにすると高さが低くなります。
border-radius: 8px;はカードの角丸です。0にすると四角いカードになり、数値を大きくすると丸みが強くなります。
カード同士の間隔を変更する場合は、親コンテナのgapを変更し、子カードのwidthも新しい間隔に合わせて計算してください。

カードの枚数と背景色を変更する方法
カードの枚数を増やす場合は、index.htmlの.flexbox-column-count_container内に、同じクラス名のdiv要素を追加します。カードを減らす場合は、不要な要素を削除してください。

<!-- 指定した列数で並べる5枚のカード -->
<div class="flexbox-column-count_container">
  <div class="flexbox-column-count_card"></div>
  <div class="flexbox-column-count_card"></div>
  <div class="flexbox-column-count_card"></div>
  <div class="flexbox-column-count_card"></div>
  <div class="flexbox-column-count_card"></div>
</div>

カードの背景色は、style.cssの:nth-child()で1枚ずつ指定しています。例えば、1枚目の色を変更する場合は、.flexbox-column-count_card:nth-child(1)のbackgroundを書き換えます。
6枚目以降を追加する場合は、対応する:nth-child(6)などのCSSも追加してください。背景色を指定しないカードは、今回のCSSでは透明になります。

レスポンシブ対応
style.cssでは、@media (max-width: 640px)を使用して、画面幅が640px以下になった場合の表示を変更しています。
スマートフォンではカードを2列にし、間隔を16px、高さを120pxに変更しています。

/* =========================================
  スマートフォン:2列
========================================= */

@media (max-width: 640px) {

  /* 画面幅640px以下では全体の余白とカード間隔を調整する */
  .flexbox-column-count_container {
    gap: 16px; /* カード同士の間隔を16pxに変更する */
    margin: 24px auto 0; /* 上24px・左右自動・下0の余白 */
    padding: 16px; /* 外枠とカードの間隔を16pxに変更する */
  }

  /* カードを2列に変更する */
  .flexbox-column-count_card {
    width: calc((100% - 16px) / 2); /* 16pxの隙間1か所を引き、残りを2等分する */
    height: 120px; /* カードの高さを120pxに変更する */
  }

}

2列ではカード同士の隙間が1か所なので、100%から16pxを引いて2等分しています。
スマートフォンでも3列にしたい場合は、メディアクエリ内のwidthをcalc((100% - 32px) / 3)に変更します。この場合は16pxの隙間が2か所になります。
スマートフォンでもカード同士の間隔をなくしたい場合は、メディアクエリ内のgap: 16px;をgap: 0;に変更し、width: calc(100% / 2);を指定してください。
PCとスマートフォンでは別々に列数を設定できるため、それぞれの画面幅に合わせて調整できます。


こちらもおすすめ


コメント