BLOG

Web制作スクールブログ

CSS Gridで3列レイアウトを作る方法|repeat()・1fr・gap・レスポンシブ対応を解説

Webサイト制作では、制作実績やサービス、商品一覧など、複数の要素を3列で並べるレイアウトをよく使います。Webデザインをしている方なら、3列の横並びレイアウトを目にする機会は多いでしょう。コーディングを中心に学んでいる方も、デザインカンプで3つの要素が横に並んだセクションをよく見かけるのではないでしょうか。

CSS Gridを使えば、grid-template-columns: repeat(3, 1fr); と指定するだけで、横幅を細かく計算することなく、3列のレイアウトをシンプルに作ることができます。

ただ、はじめてCSS Gridを使うと、「repeat()って何?」「1frはどういう意味?」「gapを入れたときの横幅はどうなるの?」と疑問に感じる方も多いのではないでしょうか。また、実際のWeb制作では3列にできれば終わりではありません。画面幅が小さくなったときに2列・1列へ変更したり、5つの要素を3列で並べたときに最後の2つをどう配置するかなど、レイアウトに合わせた調整も必要になります。

この記事では、CSS Gridで3列レイアウトを作る基本から、repeat()1frgapの考え方、レスポンシブ対応までを実例を交えながらわかりやすく解説します。

コードをそのまま覚えるだけではなく、「なぜこの指定で3列になるのか」を理解し、自分でレイアウトを調整できるようになることを目指していきましょう。

CSS Gridで3列レイアウトを作る基本

CSS Gridで3列レイアウトを作る場合、まずは複数の要素をまとめる親要素を用意し、その親要素にGridを指定します。

たとえば、6つのカードを3列で並べる場合は、次のようなHTMLを用意します。

<div class="card-list">
  <div class="card">カード1</div>
  <div class="card">カード2</div>
  <div class="card">カード3</div>
  <div class="card">カード4</div>
  <div class="card">カード5</div>
  <div class="card">カード6</div>
</div>

続いて、親要素の.card-listにCSS Gridを指定します。

.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

イメージとしては次のような配置です。

CSS Gridで.card-listを親要素にし、6つの.cardを3列で配置する例

display: grid;で親要素をGridコンテナにし、grid-template-columnsで列の数と横幅を指定します。
今回のgrid-template-columns: repeat(3, 1fr);は、簡単に言うと「同じ幅の列を3つ作る」という指定です。

grid-template-columnsは何を指定するプロパティ?

grid-template-columnsは、CSS Gridで列の数や横幅を決めるためのプロパティです。
少し長い名前ですが、単語を分けて考えるとイメージしやすくなります。

  • grid:Gridレイアウトに関する指定
  • template:レイアウトの型・設計図を決めるイメージ
  • columns:列

つまり、grid-template-columnsは、「Gridレイアウトの列をどのような形にするか決める」ための指定だと考えると分かりやすいでしょう。

たとえば、

grid-template-columns: 1fr 1fr 1fr;

と指定すると、同じ幅の列を3つ作ることができます。

今回の記事では、同じ1frを3回書く代わりに、repeat()を使って次のように記述しています。

grid-template-columns: repeat(3, 1fr);

さらに各要素間(今回は.card)の余白を設定したいときは、gap: 24px;を指定することで、カード同士の間隔を24pxに揃えることができます。

にゃんこす
にゃんこす

gapについては別記事で詳しく解説するよ🐱
ここでは要素同士の間隔(余白)を統一して設定するときに使うんだなという理解で大丈夫!

ここまでを見るとコード自体はとてもシンプルですが、repeat(3, 1fr)の中にあるrepeat()1frが何を意味しているのか分からない方もいるかもしれません。

次のセクションでは、この指定を分解しながら、なぜ3列のレイアウトになるのかを詳しく見ていきましょう。

repeat(3, 1fr)は何を意味している?

CSS Gridで3列レイアウトを作るときによく使うのが、次の指定です。

grid-template-columns: repeat(3, 1fr);

コードだけを見ると少し分かりにくいですが、意味を分解するとそれほど難しくありません。

repeat()は同じ指定を繰り返すための書き方

repeat()は、同じ列幅を何度も書く代わりに、まとめて指定できるCSS Gridの記述方法です。

たとえば、grid-template-columns: 1fr 1fr 1fr;grid-template-columns: repeat(3, 1fr);は同じ意味になります。repeat(3, 1fr)の最初の3は「3回繰り返す」という意味なので、今回は同じ幅の列を3つ作っています。

1frは残っている横幅を分ける単位

frは、CSS Gridで使用できるスペースを分配するときに使う単位です。

今回のように、

repeat(3, 1fr)

と指定した場合は、使用できる横幅を3つの列に均等に分けます。

イメージすると、

|   1fr   |   1fr   |   1fr   |

のような状態です。

そのため、それぞれのカードにwidth: 33.333%;やwidth:calc(100% / 3);のような横幅を個別に指定しなくても、3列を同じ幅に揃えることができます。
ただし、Flexboxなどでこのように要素の横幅を直接3等分した場合、gapを追加すると、その余白分も含めて横幅を調整する必要があります。

gapを入れても横幅を自分で計算する必要がない

CSS Gridでは、gapでカード同士の間隔を指定した場合も、その間隔を除いた残りの横幅を各列に分配してくれます。

.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

たとえば、上記のCSSで親要素の横幅が1200pxだと仮定すると、gap:24px;を指定することで、3列の各要素の間には24pxのgapが2つ入ります。

CSS Gridでは、その48px分を除いた残りの横幅を3列に均等に分けるため、カードの横幅を自分で計算する必要がありません。

にゃんこす
にゃんこす

これがFlexboxで同じ3列レイアウトを作るとなると、
書き方によってはgapを考慮しながらカード幅を計算する必要が出るから、
ここがちょっと面倒なんだよー😾
にゃんこすはその昔、Flexbox一択 かつ gap使ってなかったから、
電卓使って余白計算してcalc()で指定してたよ😹

この列数と間隔を親要素側でまとめて管理できるという点は、CSS Gridで複数列レイアウトを作る大きなメリットのひとつです。

2列・4列・5列に変更する方法

CSS Gridでは、repeat()の最初の数字を変更することで、列数を簡単に変えることができます。

3列の場合は、以下のように指定しました。

.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

上記コードのrepeat(3, 1fr)の「3」は「同じ幅の列を3つ作る」という意味なので、たとえば2列にしたい場合は次のように変更します。

grid-template-columns: repeat(2, 1fr);

4列にしたい場合も同じように数字を変えるだけです。

grid-template-columns: repeat(4, 1fr);

さらに、5列にしたい場合も同じように数字を変えて指定するだけです。

grid-template-columns: repeat(5, 1fr);

つまり、基本的には次のように考えると分かりやすいでしょう。

repeat(2, 1fr) → 2列
repeat(3, 1fr) → 3列
repeat(4, 1fr) → 4列
repeat(5, 1fr) → 5列

repeat(3, 1fr)は「3列レイアウト専用の決まった書き方」ではなく、作りたい列数に合わせて数字を変更できる指定です。ただし、列数を増やせばよいというわけではありません。

たとえば5列にすると、1つひとつの要素に使える横幅は3列の場合より狭くなります。カード内に画像や長いテキスト、ボタンなどが入る場合は、内容が窮屈にならないか確認しながら列数を決めることが大切です。

Web制作では「PCだから5列」「タブレットだから3列」と数字だけで決めるのではなく、実際のコンテンツが読みやすく、レイアウトとして成立する横幅になっているかを見ながら調整しましょう。

5つのカードを3列で並べたとき、最後の2つを中央寄せする方法

3列のGridレイアウトに5つの要素を入れると、以下のように1行目には3つ、2行目には2つの要素が配置されます。

[カード1] [カード2] [カード3]
[カード4] [カード5]

これはCSS Gridとして正しい配置ですが、実際の制作現場では2行目の2つが左側に寄っていることで、少しアンバランスに見える場合があります。つまり上記の図ですと、[カード3]下の余白だけが悪目立ちするのでこの部分を調整することが非常に多いです。

最後の2つは自動では中央寄せされない

たとえば、次のように3列を指定していても、

.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

5つのカードは基本的に左から順番に配置されるため、最後の2つだけが自動的に中央へ移動するわけではありません。grid-template-columns: repeat(3, 1fr);を指定した時点で、Gridには「3列」という共通の列構造が作られています。

そのため、5つのカードを配置すると、次のような状態になります。

CSS Gridで5つのカードを3列に配置したとき、2行目の3列目が空く例

2行目だけを2列として並べ直しているわけではなく、1行目と同じ3列のうち、3列目に配置するアイテムがない状態です。

ここはFlexboxとの大きな違いです。Flexboxで折り返した場合は、それぞれの行(Flexライン)ごとにアイテムを配置できますが、CSS Gridでは行が変わっても同じ列構造を共有します。
そのため、Flexboxと同じ感覚でjustify-content: center;を指定しても、2行目のカード4・5だけを中央に寄せることはできません。

あくまで、この場合に使用するjustify-contentはGridアイテムの最終行だけを中央寄せするものではなく、Grid全体の列(トラック)の配置を調整するためのプロパティです。
最後の行にある2つのカードだけを中央寄せする指定ではありません。

6分割のGridを使って最後の2つを中央に配置する

3列のカード幅を維持したまま最後の2つを中央に寄せたい場合は、Gridを内部的に6列へ分割し、それぞれのカードに2列分を使わせる方法があります。

.card-list {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 24px;
}

.card {
  grid-column: span 2;
}

.card:nth-last-child(2) {
  grid-column: 2 / span 2;
}

grid-columnは、Gridアイテムを横方向に「どこから、何列分使って配置するか」を指定するプロパティです。今回のspan 2は「2列分使う」という意味です。
また、grid-column: 2 / span 2;では、左端から1列分を空けて、その次の位置から2列分を使うように指定しています。
grid-columnの詳しい使い方については、別の記事で解説します。

CSS Gridを6列に分け、5つのカードの最後の2つを中央に配置する方法

ここでは、見た目は3列のままにしつつ、カードの位置を細かく調整できるように、親要素(.card-list)を内部的に6つの列へ分けています。

そして、1つのカードにgrid-column: span 2;を指定し、6列のうち2列分を使わせます。

つまり、

  • カード1:2列分
  • カード2:2列分
  • カード3:2列分

となり、2列分 × 3枚 = 6列分を使うため、見た目はこれまでと同じ3列レイアウトになります。

そこに、5枚のカード(.card×5)を配置すると、2行目にはカード4とカード5が残ります。

そこで、後ろから2番目のカード(カード4)に

.card:nth-last-child(2) {
  grid-column: 2 / span 2;
}

と指定し、左端の1列分を空けた位置からカード4を配置します。

カード5はその続きに自動で配置されるため、最終的には、以下のような並びになります。

左に1列分の空き カード4(2列分)カード5(2列分) 右に1列分の空き

左右に同じ1列分の空きができることで、2行目の2枚を中央に配置できます。

nth-last-child(2)後ろから2番目の要素を指定するセレクタです。
今回の5つのカードでは[カード4]が対象になり、その開始位置を2列目へ移動することで、カード5も続いて配置され、2つを中央に寄せられます。

にゃんこす
にゃんこす

このケースだけなら、実はFlexboxの方が中央寄せはわかりやすいよ!
justify-content: center;で折り返した2行目を中央に配置できるんだ。ただし、3列の横幅を揃えるにはgapを含めた幅計算が必要になるよ。
GridとFlexboxは「どっちが優秀」ではなく、レイアウトによって得意・不得意があるんだよ🐱

ちなみにFlexboxの場合を例で書くとこんな感じー🐾

.card-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
}

.card {
  box-sizing: border-box;
  width: calc((100% - 48px) / 3);
}

必ず中央寄せする必要があるわけではない

最後の行が左寄せになること自体は間違いではありません。

カード一覧のデザインや他のセクションとの整合性によっては、

[カード1] [カード2] [カード3]
[カード4] [カード5]

のままの方が自然な場合もあります。

「Gridだから中央寄せにする」のではなく、デザインとしてどちらが見やすいかを判断して調整することが大切です。

3列レイアウトをレスポンシブ対応する

PCでは3列で見やすいレイアウトでも、スマートフォンのように画面幅が狭くなると、1つひとつのカードが小さくなり、文字や画像が見づらくなることがあります。

そのため、実際のWeb制作では画面幅に合わせて、以下のように列数を変更することがあります。

  • PC:3列
  • タブレット:2列
  • スマートフォン:1列

CSS Gridでは、grid-template-columnsの指定をメディアクエリで変更するだけで、列数を切り替えることができます。以下に例を記載します。

.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

@media (max-width: 768px) {
  .card-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .card-list {
    grid-template-columns: 1fr;
  }
}

この例では、画面幅が768px以下になると2列、480px以下になると1列へ変更しています。

CSS GridでPCは3列、タブレットは2列、スマートフォンは1列に切り替えるレスポンシブレイアウトの例

ブレイクポイントは決まった数字ではない

ただし、「タブレットは768px」「スマートフォンは480px」と必ず決める必要はありません。
カード内の文字量や画像の大きさ、余白などによって、読みやすい横幅は異なります。

実際のWeb制作では、画面を縮めながらレイアウトを確認し、「3列では窮屈になってきた」と感じる位置で2列へ変更するなど、デザインに合わせてブレイクポイントを決めることが大切です。

にゃんこす
にゃんこす

「768pxになったら2列!」と数字だけ覚えなくても大丈夫!カードの文字が窮屈になったり、画像が小さくなりすぎたりしたところが、レイアウトを切り替えるひとつの目安だよ。
にゃんこすも実制作では、UIデザインの見え方に合わせてブレイクポイントを細かく追加することがあるよ。PC・タブレット・スマホの3段階だけで考えるのではなく、「この幅だと少し窮屈だな」と感じたところで調整することもあるニャ🐾

画面幅に合わせて列数を自動調整する方法もある

ここまで紹介した方法では、メディアクエリを使って3列・2列・1列と列数を切り替えてきました。
CSS Gridではこのほかにも、auto-fitminmax()を組み合わせることで、画面幅に合わせて列数を自動で調整する方法があります。

たとえば、次のように指定できます。

.card-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px;
}

この指定では、1つのカードの横幅を最低240px確保しながら、表示できる数に合わせてGridの列数が自動で変化します。

そのため、画面幅によって、

広い画面     → 3列・4列
少し狭い画面 → 2列
狭い画面     → 1列

のように、メディアクエリで列数を1つずつ指定しなくてもレイアウトを調整できます。

にゃんこす
にゃんこす

「じゃあ全部これでいいのでは?」と思うかもしれないけど、デザインによっては「この画面幅までは必ず3列にしたい」ということもあるよ。
メディアクエリで明確に切り替える方法と、自動調整する方法を使い分けるのがポイントニャ🐾

minmax()auto-fitはCSS Gridを使ううえでとても便利ですが、それぞれの意味を理解していないと少し分かりにくい指定でもあります。
minmax()auto-fitを使ったレスポンシブレイアウトについては、別の記事で詳しく解説します。

CSS Gridで3列レイアウトを作るときの考え方

CSS Gridを使えば、repeat(3, 1fr)で簡単に3列レイアウトを作れます。
ただし、実際のWeb制作では「3列にできるから3列にする」のではなく、カードの内容や画面幅に合わせて、読みやすい列数を考えることが大切です。

たとえば、次のようなポイントを確認します。

  • カード内の文章が窮屈になっていないか
  • 画像が小さくなりすぎていないか
  • ボタンや見出しが不自然に折り返していないか
  • gapを含めても十分な余白が確保できているか
  • 画面幅が変わったときも見やすいレイアウトになっているか

PCでは3列がきれいに見えていても、カード内の情報量が多い場合は2列の方が読みやすいこともあります。逆に、内容がシンプルなカードであれば、画面幅によっては4列以上でも見やすく配置できることがあります。

にゃんこす
にゃんこす

「PCだから3列」「タブレットだから2列」と決め打ちするのではなく、実際のデザインを見ながら考えるのが大事だよ。CSSの書き方だけでなく、どの列数なら内容が一番見やすいかを判断することもWeb制作の一部ニャ🐾

まとめ|CSS Gridで3列レイアウトを作ってみよう

CSS Gridを使えば、grid-template-columns: repeat(3, 1fr);を指定することで、3列レイアウトをシンプルに作ることができます。

今回の記事では、3列レイアウトの基本から、repeat()1frgapの考え方、列数の変更、5つのカードを配置するときの調整、レスポンシブ対応まで紹介しました。

特に覚えておきたいポイントは次のとおりです。

  • repeat(3, 1fr)で同じ幅の3列を作れる
  • gapを使えば、カード幅を細かく計算せずに間隔を設定できる
  • repeat()の数字を変えることで2列・4列・5列などにも変更できる
  • 画面幅が狭くなったら、メディアクエリで2列・1列へ切り替えられる
  • auto-fitminmax()を使って列数を自動調整する方法もある
  • CSS GridとFlexboxにはそれぞれ得意なレイアウトがある

CSS Gridは、コードをそのまま覚えるよりも、なぜこの指定でこのレイアウトになるのかを理解すると、自分でデザインに合わせて調整しやすくなります。

Web制作では、CSSのプロパティを知っているだけでなく、「このデザインなら何列が見やすいか」「FlexboxとGridのどちらを使うか」「どの画面幅でレイアウトを変更するか」といった判断も大切です。

にゃんこす
にゃんこす

最初はrepeat()1frが少し難しく見えるかもしれないけど、実際にカードを並べながら触ってみると、だんだん仕組みが見えてくるよ。
AppRizzでは、こうしたCSSの書き方だけでなく、実際のWeb制作でどう考えて使い分けるかも一緒に学んでいくニャ🐾気になった人は公式LINEやお問い合わせフォームから気軽に相談してね🐱

あと一歩を埋めて、あなたのスキルを
仕事に変えませんか?

まずは無料カウンセリングへ

オンラインで開催中

※無理な勧誘などは一切ありませんので、ご安心ください。

お気軽にお問い合わせ・ご相談ください

にゃんこす