今回はグリッドレイアウトについて紹介していきます。グリッドレイアウトは格子状のグリッドに子要素のボックスを配置していくレイアウトです。displayプロパティを「gird」に指定すればグリッドレイアウトができます。

「display:gird;」の対応ブラウザを見てみましょう。

グリッドレイアウト対応ブラウザ
capture1. グリッドレイアウト対応ブラウザ(2017年11月22日 現在)

最新のグリッドレイアウトの対応状況はこちら

ほとんどのブラウザで対応しています。IE11だけprefixが必要で -ms- を付ける必要があり、グリッドレイアウトの古い規格で書く必要があります。今回はprefixを考慮せずにコードを書いていきます。

使用していくhtmlコードは以下のものを使用していきます。

code1

<div class="grid-container">
  <div class="grid-item boxA">A</div>
  <div class="grid-item boxB">B</div>
  <div class="grid-item boxC">C</div>
  <div class="grid-item boxD">D</div>
  <div class="grid-item boxE">E</div>
  <div class="grid-item boxF">F</div>
</div>

グリッドレイアウトの作成

code1をそのまま表示すればfg1.のように表示されます。

grid指定前
fg1.grid指定前

code2

.grid-container{
  display: grid;
  width: 600px;
  height: 300px;
  grid-template-rows: 100px 120px;
  grid-template-columns: 350px 100px 120px;
}
grid指定後
fg2.grid指定後

code2を指定すれば、fg2.のように表示されます。

「grid-template-rows」はグリッドの行の高さを、
「grid-template-columns」はグリッドの列の幅を指定できます。
code2は2行×3列のグリッドを作成できます。

code2はgrid-template-rows,grid-template-columnsのサイズをpx指定していますが、それ以外にも指定方法がいろいろあります。

px指定以外のgrid-template-rows,grid-template-columnsのサイズ指定方法を見ていきましょう。


フレキシブルな単位 「fr」

グリッドレイアウトで使用するために用意された新しい単位「fr」です。値にはコンテナのスペースを分け合う比率を指定します。

例えばcode3のように指定すると、fg3.のように表示されます。

code3

.grid-container{
  display: grid;
  width: 600px;
  height: 300px;
  grid-template-rows: 1.5fr 1fr;
  grid-template-columns: 150px 2fr 1fr;
}
単位「fr」使用例
fg3.単位「fr」使用例

fg3.では行は1.5:1の比率で、列は150px:2:1の比率でグリッドが作成されています。

行は300pxを1.5:1の比率で分けるので、180px:120pxになっています。

列は1列目は150pxとなっているので、残りの450pxを2:1の比率で分け、300px:150pxになっています。


グリッドアイテムの最小値・最大値の指定 「minmax」

minmax()を用いれば、グリッドアイテムの最小値・最大値を指定できます。code3では行が180px:120pxになっていましたが、code4のように書くと、行は150px:150pxで分けられます。

code4

.grid-container{
  display: grid;
  width: 600px;
  height: 300px;
  grid-template-rows: 1.5fr minmax(150px,1fr);
  grid-template-columns: 150px 2fr 1fr;
}

グリッドアイテムのコンテンツに合わせたサイズにする

min-content、max-content

グリッドアイテム幅をグリッドアイテム内のコンテンツの最小サイズにする場合は「min-content」、最大サイズにする場合は「max-content」と指定します。
code5のように記述します。

code5

.grid-container{
  display: grid;
  width: 600px;
  height: 300px;
  grid-template-rows: 1.5fr min-content;
  grid-template-columns: max-content 2fr 1fr;
}

auto

値を「auto」と指定すると、「minmax(min-content,max-content)」と指定したときと同じようになります。


fit-content

code6のように指定すると、グリッドアイテム内のコンテンツの最大サイズが150px未満のときは「auto」で、コンテンツの最大サイズが150px以上のときは「minmax(auto,150px)」として処理されます。

code6

.grid-container{
  display: grid;
  width: 600px;
  height: 300px;
  grid-template-rows: 1.5fr 1fr;
  grid-template-columns: fit-content(150px) 2fr 1fr;
}

同じパターンが連続するグリッドの指定 「repeat」

code8のように同じパターンが連続する場合はcode9のように書き換えることができます。

code7

.grid-container{
  display: grid;
  grid-template-rows: 300px;
  grid-template-columns: 80px 20px 50px 80px 20px 50px;
}

code8

.grid-container{
  display: grid;
  grid-template-rows: 300px;
  grid-template-columns: repeat(2,80px 20px 50px);
}

レスポンシブなグリッドを作成

「repeat」を利用するとメディアクエリを使用しなくてもレスポンシブなグリッドを作成できます。
grid-template-columns: repeat(auto-fill,minmax(100px,1fr)); のように指定すれば、windowサイズによって列数が変わります。
下記のサンプルをご確認ください。

See the Pen eeGyMp by blanks (@blanks-site) on CodePen.


グリッドアイテムの配置方向 「grid-auto-flow」

grid-auto-flowを使用すると、グリッドアイテムを配置する方向を指定できます。
初期値は「row」で左から右、上から下の順に配置されます。(fg.4参考)
「column」を指定すると上から下、右から左の順に配置されます。(fg.5参考)

grid-auto-flow:row
fg4. grid-auto-flow:row
grid-auto-flow:column
fg5. grid-auto-flow:column

またgrid-auto-flowにはdenseという値があります。
こちらは「grid-auto-flow: row dense;」や「grid-auto-flow: column dense;」と指定します。
「dense」を指定すると下記のようになります。

See the Pen Grid layput grid-auto-flow by blanks (@blanks-site) on CodePen.



ラインを指定してグリッドアイテムを配置

グリッドアイテムの配置をグリッドラインを使用して指定することもできます。
グリッドラインとは、グリッドアイテムを区切るラインのことで、グリッドを作成すると自動的に割り当てられます。(code9、fg.6参照)

code9

.grid-container{
  display: grid;
  grid-template-rows: 1.5fr 1fr 1fr;
  grid-template-columns: 1fr 2fr 1fr;
}
グリッドラインの作成
fg6. グリッドラインの作成

このグリッドラインを利用して、グリッドアイテムを配置できます。
グリッドラインのプロパティには「grid-row-start」「grid-row-end」「grid-column-start」「grid-column-end」があり、これでグリッドアイテムの配置が指定できます。(code10参照)
「grid-row-start」と「grid-column-start」だけで指定もできます。
DEMOで確認

code10

.grid-item{
  grid-row-start: 2;     /* 行の始点 */
  grid-row-end: 3;       /* 行の終点 */
  grid-column-start: 3;  /* 列の始点 */
  grid-column-end: 4;    /* 列の終点 */
}

グリッドラインのプロパティには「span」が使用でき、複数行・複数列に渡ってグリッドアイテムを配置できます。(code11参照)
DEMOで確認

code11

.grid-item{
  grid-row-start: 2;
  grid-row-end: span 2;
  grid-column-start: 1;
  grid-column-end: span 2;
}

ここまで説明してきた「grid-row-start」「grid-row-end」「grid-column-start」「grid-column-end」ですが、
「grid-row-start」「grid-row-end」は「grid-row」で
「grid-column-start」「grid-column-end」は「grid-column」で
一括して指定できます。
code11はcode12のようにも記述できます。

code12

.grid-item{
  grid-row: 2 / span 2;
  grid-column: 1 / span 2;
}

グリッドラインで配置を指定すると、グリッドアイテムを重ねて指定することもできます。このとき重なり順はz-indexで指定できます。(code13参照)
DEMOで確認

code13

.boxA{
  grid-row: 2 / span 2;
  grid-column: 1 / span 2;
}
.boxB{
  grid-row: 1 / span 2;
  grid-column: 2 / span 2;
  background-color: #aaa;
}

DEMO「grid-row,grid-column」

See the Pen Grid layput grid-row,grid-column by blanks (@blanks-site) on CodePen.


エリアを指定してグリッドアイテムを配置

グリッドアイテムはグリッドラインだけではなく、グリッドエリアで配置を指定することもできます。
先に下記のデモをご確認ください。

DEMO「grid-template-areas,grid-area」

これまでDEMOのようなレイアウトを組もうと思ったら、floatを駆使して、多くのdivタグを使用しなければいけませんでした。
しかしグリッドレイアウトを使用すれば、DEMOのhtmlは「code14」のようにかなり簡素化できます。

code14

<div class="grid-container">
   <div class="grid-item keyImage-item">keyImage area</div>
   <div class="grid-item side-item">side area</div>
   <div class="grid-item bread-item">bread area</div>
   <div class="grid-item main-item">main area</div>
   <div class="grid-item sub1-item">sub1 area</div>
   <div class="grid-item foot-item">foot area</div>
   <div class="grid-item copyright-item">copyright area</div>
</div>

どのようにcode14のような簡素化したhtmlでレイアウトしているのか。
グリッドエリアでの配置では「grid-template-areas」と「grid-area」のプロパティを使用します。

「grid-template-areas」はcode15のようにグリッドコンテナに指定します。
1行ごとの区切りは「" "」を使用し、1列ごとの区切りは「 」(半角スペース)を使用しています。
DEMOのコンテナは5行×3列のグリッドを作成しているので、1行ごとに3つずつ「grid-area」の名前を指定できます。
例えば1行目は全て「keyImage」で占めたいので、「"keyImage keyImage keyImage"」となっています。
またgrid-area名「side」は1列目を3行に渡って占めているので、2〜4行目の最初のgrid-area名は「side」になっています。
「grid-template-areas」は、ビジュアル的な指定の仕方なので、分かりやすいと思います。

code15

.grid-container{
  display: grid;
  grid-template-areas:
    "keyImage keyImage keyImage"
    "side bread bread"
    "side main sub1"
    "side foot foot"
    "copyright copyright copyright";
  grid-template-rows: 100px 40px 300px 100px 50px;
  grid-template-columns: .3fr 2fr .3fr;
}

次にグリッドアイテムでは「grid-area」を指定しています。
これは先ほど「grid-template-areas」で指定したエリア名をグリッドアイテムに割り当ててあげるためのプロパティです。
grid-rowやgrid-columnでは「2 / span 2」のように指定して、正直わかりづらかったかと思いますが、「grid-template-areas」で指定したエリア名をグリッドアイテムの「grid-area」で指定するだけで、複数行・複数列に渡るグリッドアイテムが簡単にできます。
また、レイアウトを変更しようとする際にも、「grid-template-areas」の記述を変更するだけでレイアウトを変更できるので、管理もしやすいと思います。

code16

.keyImage-item{
  grid-area: keyImage;
}
.side-item{
  grid-area: side;
}
.bread-item{
  grid-area: bread;
}
.main-item{
  grid-area: main;
}
.sub1-item{
  grid-area: sub1;
}
.foot-item{
  grid-area: foot;
}
.copyright-item{
  grid-area: copyright;
}


グリッドアイテムの間隔を指定

次はグリッドアイテム同士の間隔を調整するプロパティ「grid-gap」です。
これはグリッドコンテナに指定するプロパティです。

ここで気になるのはグリッドコンテナやグリッドアイテムのサイズがどのようになるかだと思います。
まずcode17に全てpx指定した場合、グリッドコンテナやグリッドアイテムのwidthはheightどうなるのか。DEMOも作成したので、確認してみてください。

code17

.grid-container{
  display: grid;
  grid-template-areas:
    "item1 item1 item2"
    "item3 item4 item2";
  grid-template-rows: 50px 100px;
  grid-template-columns: 200px 150px 150px;
  width: 500px;
  grid-gap: 10px;
}
.item1{
  grid-area: item1;
}
.item2{
  grid-area: item2;
}
.item3{
  grid-area: item3;
}
.item4{
  grid-area: item4;
}

See the Pen Grid layput grid-gap by blanks (@blanks-site) on CodePen.

確認してみて分かるように、「item3」、「item4」はgrid-template-rows、grid-template-columnsで指定した通りの大きさですが、「item1」や「item2」は指定した大きさ+「grid-gadの値」になっています。
また「grid-container」に関しては、widthを500pxで指定していますが、実際は520pxになっています。

グリッドアイテムに指定している大きさが優先させることがわかります。


「fr」だけで指定した場合は、大方予想できますが、例えば「grid-template-rows: 1fr 2fr 1fr」と指定すれば、グリッドコンテナに収まり、gird-gapの値だけ間隔を取って、1:2:1になるようにグリッドアイテムを分割してくれます。

また「fr」と「px」でした場合は、px指定は指定したpxのwidthやheightになり、「fr」で指定した箇所は指定した割合になるように分割されます。


グリッドコンテナの位置揃え

グリッドコンテナ内に余白がある場合に、グリッドコンテナをどのような位置揃えにするか指定できます。
しかしグリッドアイテムで「fr」を指定していると、余白ができないように調整されるため、グリッドコンテナの位置揃えは指定できません。

横方向の位置揃え「justify-content」プロパティと
縦方向の位置揃え「align-content」プロパティがあります。

それぞれDEMOで確認してみましょう。


justify-content

See the Pen Grid layput grid-container justify-content by blanks (@blanks-site) on CodePen.

いくつかわかりづらいものがあるので、少し補足で説明します。

「space-evenly」と「space-around」の違い

「space-evenly」…余白の均等割り

「space-around」…余白の均等割りだが、両端だけ余白が半分のサイズ

「stretch」

「grid-template-rows」や「grid-template-columns」のサイズ指定の中に「auto」がある場合、auto指定されているグリッドアイテムを引き伸ばす。


align-content

プロパティ値は「justify-content」と同じで、プロパティ値による余白の割り方も同じです。縦方向か横方向かの違いだけになります。

See the Pen Grid layput grid-container align-content by blanks (@blanks-site) on CodePen.


グリッドアイテムの位置揃え

次はグリッドアイテム内での位置揃えのプロパティです。

グリッドコンテナで指定する「justify-items」「align-items」と
グリッドアイテム個別で指定する「justify-self」「align-self」があります。
「justify-items」「justify-self」のプロパティ値は同じで、「align-items」「align-self」のプロパティ値が同じです。

「justify-items」「align-items」でグリッドアイテム全ての位置揃えを指定して、「align-items」「align-self」で個別に位置揃えを変えたいものを指定するといった使い方になると思います。


justify-items

グリッドアイテムの横方向の位置揃えを指定するプロパティです。

See the Pen Grid layput grid-container justify-items by blanks (@blanks-site) on CodePen.


align-items

グリッドアイテム縦方向の位置揃えを指定するプロパティです。

See the Pen Grid layput grid-container align-items by blanks (@blanks-site) on CodePen.


今回girdレイアウトを色々調べてみたのですが、これから使っていきたいなと思えるいいものですね。
個人的にはビジュアル的に指定できる「grid-template-areas」がすごいなと思いました。結構前から「display:grid」は検討されていたみたいで、ようやく使える感じになってきたみたいです。
これからは「display:flex」と「display:grid」でものレイアウトが主流になっていきそうですねー。

次回は「display:grid」のもっと実用的な使い方を紹介できたらいいなと思います。

display: gird; を利用したレイアウト例の記事を書きました。より実用的なグリッドレイアウトの使い方を説明しています。