logo
コーディング

更新日

CSSグリッドレイアウトで、サイズが違う複数のボックスをタイル状に配置する

大きさの異なる複数のボックスを隙間なく並べてタイル状に表示したい!そんな時もありますよね。モザイクレイアウト、Masonryレイアウト、Windows 8 Metroスタイルレイアウト…などなど、さまざまな呼び方のあるこのレイアウト。今回は display: grid という新しい配置方法を使ってレイアウトを組んでみますよ!もちろんレスポンシブにも対応させたいと思います!

CSS グリッドの基本の書き方は動画で確認!

基本的な記述方法は動画でも紹介しています。初めて CSS グリッドに挑戦するよという方はまずはこちらで基礎を覚えておきましょう!

1. どんなレイアウトにするか書き出す

グリッドレイアウトは少し複雑で、何も考えず組んでいくとどこの要素がどうなっているのか…こんがらがってきちゃいます。ご利用は計画的に!慣れるまではレイアウトを頭の中だけではなく、紙などに書き出して整理しておくとコーディングもしやすいですよ。

2. グリッドのベースを作成

まずはベースとなる HTML を記述。今回は親要素であるグリッドコンテナーに「container」、子要素であるグリッドアイテムに「item」というクラスを付与しました。

HTML

<div class="container">
  <div class="item">A</div>
  <div class="item">B</div>
  <div class="item">C</div>
  <div class="item">D</div>
  <div class="item">E</div>
  <div class="item">F</div>
  <div class="item">G</div>
  <div class="item">H</div>
  <div class="item">I</div>
  <div class="item">J</div>
  <div class="item">K</div>
</div>

CSS

.item {
  background: #ddd;
  padding: 10px;
  border-radius: 8px;
  border: 3px solid #ccc;
}

現状は子要素がただ縦に並んでいるだけです。

続いて今回の目玉である display: grid; を親要素の .container に記述します。このままだと特に変化が見られないので、子要素のグリッドアイテム間に余白を入れる gap を追加しましょう。

.container {
  display: grid;
  gap: 10px;
}

まだタイル状に並んではいませんが、グリッドアイテム(子要素)の間に余白ができました。

3. グリッドのサイズを指定

続いて各子要素のサイズを指定して、タイル状に並べていきましょう。横のサイズには grid-template-columns を、縦のサイズには grid-template-rows を利用します。

指定する数値は通常の widthheight を指定する時と同様、pxで具体的な数値を記述したり、%で割合の指定、auto でコンテンツ幅に合わせて指定できます。また、グリッドレイアウトでは fr という単位が使用できます。fr は fraction(比率)のことで、親要素から見た子要素の大きさを具体的な数値ではなく割合で表現します。

どちらのプロパティーも、必要な子要素の数だけスペースで区切って指定する必要があります。例えば今回の例だと横に 4 つのボックスが並ぶので、grid-template-columns: 1.5fr 1fr 1fr 3fr; とし、親要素の幅の 1.5:1:1:3 の比率で幅をもたせるようにしましょう。縦は最終的に 5 段にする予定なので、サイズを grid-template-rows: 180px 100px 80px 120px auto; と指定しておきます。

.container {
  display: grid;
  gap: 10px;
  grid-template-columns: 1.5fr 1fr 1fr 3fr;
  grid-template-rows: 180px 100px 80px 120px auto;
}

こんな感じでようやくグリッドレイアウトとして表示されました!

4. サイズが違う 4 つのボックスを配置

それでは今回のメインであるサイズが違うボックスを表示してみましょう。まずはサイズを変更したい子要素に対し、新たに .box-big1, .box-big2, .box-big3, .box-big4 の 4 つのクラスを追加します。

<div class="container">
  <div class="item box-big1">A</div>
  <div class="item">B</div>
  <div class="item">C</div>
  <div class="item">D</div>
  <div class="item">E</div>
  <div class="item box-big2">F</div>
  <div class="item box-big3">G</div>
  <div class="item">H</div>
  <div class="item">I</div>
  <div class="item">J</div>
  <div class="item box-big4">K</div>
</div>

続いてグリッドアイテムの範囲を指定するのですが、こちらが少し特殊な指定方法になるので混乱しないよう、ひとつずつ見ていきましょう。使用するプロパティーは横の範囲を grid-column 、縦の範囲を grid-row で指定します。

こちらの図にあるように、縦・横に並ぶグリッドラインをベースに範囲を指定します。例えば横の範囲がグリッドラインの 3〜5 番目を指定するなら、「始まりのライン / 終わりのライン」というようにスラッシュで区切って grid-column: 3 / 5; と記述します。

.box-big2 {
  grid-column: 3 / 5;
}

同様に縦のラインが 1〜4 番目を指定するなら、grid-row プロパティーを使って grid-row: 1 / 4; と記述します。

.box-big1 {
  grid-row: 1 / 4;
}

grid-columngrid-row の値の書き方は、他にも終わりのラインを指定するのではなく、始まりのラインから何個分のボックスまでを範囲に含めるかの指定ができます。書き方は「始まりのライン / span 何個分まで」というように、スラッシュのあとに span を書き足します。つまり grid-row: 1 / 4;grid-row: 1 / span 3; ということですね。

.box-big1 {
  grid-row: 1 / span 3;
}

そんな感じで 4 つ分のサイズの異なるボックスを記述しました!CSS は以下のようにしています。

.box-big1 {
  grid-column: 1;
  grid-row: 1 / 4;
  background: #fc2;
  border-color: #fa0;
}
.box-big2 {
  grid-column: 3 / 5;
  background: #0bd;
  border-color: #09c;
}
.box-big3 {
  grid-column: 2 / 4;
  grid-row: 3 / 5;
  background: #c6c;
  border-color: #a4a;
}
.box-big4 {
  grid-column: 1 / 5;
  background: #0ba;
  border-color: #098;
}

5. レスポンシブ対応

最後に横幅の短いデバイスで見ると 1 カラムに並ぶよう調整しましょう。現状では指定したレイアウトを保ったまま横幅が伸縮されています。

このままでも OK な場合もありますが、コンテンツ量が多くなると複数カラムは見づらいと思うので、grid-template-columns: 1fr; を指定して親要素の範囲いっぱいに広がった 1 カラムに設定します。さらに grid-template-rows: auto; でコンテンツの高さに合わせて表示するようにします。

サイズの異なる 4 つのボックスには grid-column: 1;grid-row: auto; で範囲の指定を解除します。

@media (max-width: 600px) {
  .container {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
  }
  .box-big1,
  .box-big2,
  .box-big3,
  .box-big4 {
    grid-column: 1;
    grid-row: auto;
  }
}

※本来はモバイルファーストで大きいデバイスサイズにのみ Grid レイアウトを対応させた方が楽だと思いますが、勉強のためデスクトップファーストで作ってみました。

完成!

こんな感じでうまくタイル状に配置できました!レスポンシブ具合についてはデモ画面右上の「EDIT ON CODEPEN」をクリックして横幅を変更しながら確認してみてください!

ちなみにこの CSS グリッドレイアウトは最新版の Chrome、Safari、Firefox に対応しています。IE や Edge についてはMicrosoft のデベロッパーガイド-ms- ベンダープレフィックスを使った適応方法が紹介されています。利用できないプロパティーもあるので、一度読んでおくといいでしょう。


グリッドレイアウトには数多くのプロパティーが用意されており、一度にすべてを覚えて使いこなすのはなかなか至難の業。今回作ったグリッドをベースに少しずつカスタマイズしながら勉強していきたいですね。以下のサイトが参考になるので、ぜひ目を通してみてください!