二次元的なレイアウトが可能になる次世代のCSSレイアウト、Grid Layout Moduleについて
こんにちは、制作部 松本です。
私はこれまでCSSレイアウトでdisplay
プロパティ用いる際、inline-block
やtable
、
最近ではflexbox
を使用してきました。
今でもfloat
を多用している方はあまりいないのではないかと思います。
本記事では、よりフレキシブルなレイアウトが実現できるgrid
について紹介します。grid
は複雑なため、まだ体系的に全ての機能を説明できるほど私の理解も追いついていないので、今回はざっくりとした紹介となります。
対応ブラウザ
2017年4月現在、すでにほとんどのブラウザでgrid
が対応可能になっています。
残るはAndroid Browserのみ。
Can I Use CSS Grid Layout
gridで何ができるのか
一言で言えば、flexbox
、table
同様にマルチカラムレイアウトすることができるプロパティです。flexbox
が一次元的なレイアウトなのに対して、grid
は二次元的なレイアウトが可能(らしい)です。
gridの概要
グリッドコンテナ | display:grid; を指定された要素。 |
---|---|
グリッドアイテム | display:grid; を指定された要素の直下の子要素。孫要素はグリッドアイテムとみなされない。 |
グリッドトラック | grid のcolumn(列) とrow(行) の総称。html のtable タグをイメージしてもらうとわかりやすいです。 |
グリッドライン | グリッドトラック間の線。 |
グリッドセル | グリッドラインによって分けられた個々のスペース。 |
グリッドエリア | 複数のセルをまとめたグリッド内の特定の領域。 |
gridのプロパティ
グリッドコンテナのプロパティ
grid | 要素をグリッドコンテナとして定義する。 |
---|---|
grid-template-columns | グリッドトラック(列)のサイズを指定する。 |
grid-template-rows | グリッドトラック(行)のサイズを指定する。 |
grid-template-areas | グリッドエリアの名前を参照して、グリッドテンプレートを定義する。 |
grid-template | grid-template-columns 、grid-template-rows 、grid-template-areas を指定できるショートハンド。 |
grid-column-gap | グリッドトラック(列)の間を指定する。 |
grid-row-gap | グリッドトラック(行)の間を指定する。 |
grid-gap | grid-column-gap 、grid-row-gap を指定できるショートハンド。 |
justify-items | グリッドアイテムの行方向の整列。 |
align-items | グリッドアイテムの列方向の整列。 |
justify-content | グリッドトラックの行方向の整列。 |
align-content | グリッドトラックの列方向の整列。 |
grid-auto-columns | 自動的に生成されたグリッドトラックのサイズを指定する。 |
grid-auto-rows | 自動的に生成されたグリッドトラックのサイズを指定する。 |
grid-auto-flow | 明示的に配置されていないグリッドアイテムの配置を指定する。 |
グリッドアイテムのプロパティ
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-template-areas プロパティで参照できるようにする。grid-column 、grid-row のショートハンドでもある。 |
justify-self | グリッドアイテム内のコンテンツを行方向に整列する。 |
align-self | グリッドアイテム内のコンテンツを列方向に整列する。 |
サンプル
上図のようなレイアウトを実現する場合、HTML/CSSの構造はとても単純です。
HTML
<div class="container">
<div class="item item-a">A</div>
<div class="item item-b">B</div>
<div class="item item-c">C</div>
<div class="item item-d">D</div>
<div class="item item-e">E</div>
<div class="item item-f">F</div>
</div>
CSS
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px;
grid-gap: 10px;
color: #444;
}
.item {
background: #bbb;
color: #fff;
padding: 10px;
font-size: 150%;
}
.item:nth-child(odd) {
background: #333;
}
このコードを図解すると↓のようになります。
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px;
この記述は嚙み砕くと、width100pxのグリッドアイテムを3列
height100pxのグリッドアイテムを2行
ということです。
ちなみにショートハンドで書くとこんな感じです。
grid-template:100px 100px / 100px 100px 100px;
grid-template-columns
を以下のように変更します。
grid-template-columns: 100px 100px 100px 100px;
するとwidth100pxのグリッドアイテムを4列
になるので、Dのグリッドアイテムが1行目に移動します。
グリッドアイテムの数が多い場合、repeat
を使うと便利です。
grid-template: repeat(5, 100px) / repeat(5, 100px);
これは↓と同じ意味です。
grid-template-columns: 100px 100px 100px 100px 100px;
grid-template-rows: 100px 100px 100px 100px 100px;
Aのグリッドアイテムだけ、横幅を広げたい場合、
.item-a {
grid-column:span 4;
}
これはtable
タグのcolspan="4"
と同様の動きをします。
このとき、Fのグリッドアイテムのheight
が100px以下になっていますが、
それはgrid-template-rows: 100px 100px;
の記述で、2行目までしかheight
を指定していないためです。
次に、grid
でもっとも重要と思われるgrid-area
について説明します。
この機能を使うためには、まずテンプレートに定義したい要素
に名前をつけます。
.item-a {
grid-area: area-a; /* .item-aにarea-aという名前をつける */
}
.item-b {
grid-area: area-b;
}
.item-c {
grid-area: area-c;
}
.item-d {
grid-area: area-d;
}
.item-e {
grid-area: area-e;
}
.item-f {
grid-area: area-f;
}
グリッドコンテナにテンプレートを定義します。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px;
grid-template-areas:"area-a area-b area-c"
"area-d area-e area-f";
grid-gap: 10px;
color: #444;
}
grid-template-areas
の値はそのままグリッドアイテムの並びと連動します。
・グリッドアイテムの順番を変える場合
grid-template-areas:"area-e area-c area-b"
"area-f area-a area-d";
・グリッドアイテムの要素を広げる場合
grid-template-areas:"area-e area-c area-c"
"area-e area-a area-f"
"area-b area-d area-d";
・グリッドエリア内に空白部分が欲しい場合
grid-template-areas:"area-e area-c ......"
"area-e area-a area-f"
"area-b area-d area-d";
視認性を考え他のエリア名と文字数を揃えていますが、「.」はひとつでも構いません。
・複雑なレイアウトの場合
grid-template-areas:"area-a ...... ...... area-c"
"...... area-e area-f area-c"
"area-b area-b area-f area-c"
"...... area-d ...... area-c";
こんな面倒くさそうなレイアウトもとても簡単です!
grid特有の単位
グリッドアイテムのサイズにはpx
、em
、rem
以外にfr(flex fraction)
が指定できます。
grid-template-columns: 200px 2fr 1fr;
grid-template-rows: 200px 200px;
fr
は、グリッドアイテムの配置可能な領域を占める割合を表します。flexbox
のflex-grow
と同様の動きをすると考えるとわかりやすいです。
2fr
は1fr
の2倍の幅になります。
まとめ
ざっくりとした紹介にはなりましたが、いかがでしたでしょうか?
恐らくgrid
の機能の10分の1程度しか紹介できていませんが、もっと色々な機能を使いこなせるようになれば最強の武器になると思います。
Androidでも対応可能になるその日までに、少しでも理解を進めておいて損はないのではないでしょうか!