メニューを閉じる

テクノデジタルグループ

メニューを開く

2018.01.12

プログラミング

2次元レイアウトを簡単に! CSS Gridを使ってみた

こんにちは、shiroです。

前回の記事でキャッチに使用した画像(下)、作成が面倒だったんですよね。
materialmixier
変形は画像編集ソフトを使ったのですが、配置が……。
positionやfloatを利用して配置を決めていました。
その時、どこからか声がしたのです。「ちょっと待った!」と。
「CSS Gridを使えば簡単だよ!」その声は言うのです。

ということで、今回CSS Gridを触ってみました。

CSS Gridとは

w3cの該当ページを読むに、CSS Gridは正確にはCSS Grid Layoutと呼ぶようです。
本記事ではCSS Gridと呼ぶこととします。

CSS Gridは2次元レイアウト(行と列の要素によって作成されるレイアウト)の作成が簡単にできる新しいレイアウトモデルになります。
テーブルも行と列によって作成されていますね。
でも、下図をご覧ください。
table_and_grid
テーブル内の要素は決まった箇所に配置されますが、CSS Gridでは内部の要素がグリッドに沿っていれば(重なるとしても!)自由な場所に自由な大きさで配置することができます。
またCSS Flexible Box Layout で作成していたようなものが、より簡単に作成できるようになるようです。
これだけでもうワクワクしませんか?

現在のw3cステータスは勧告候補なので変更に注意が必要ですが、Can I Useによるとほぼすべてのブラウザが対応しています。
2017-11-01_16h01_24
プレフィックスが必要ですがIEでも使用可能です。

CSS Gridの書き方

CSS Gridを書く方法はショートハンドを含めると多岐にわたります。
そのため本記事では基本的な書き方から始め、徐々にショートハンドに変更していくようにします。
なお、本記事の内容は基本的な部分のみで、すべてのプロパティを網羅することはありませんので、気になる人は各自で調べるようにしてください。

まずはHTMLを記述します。
body要素の中身のみ抜粋しました。

1
 
2
 
3
 
4
 
5

divの中に複数のdivが入っているだけです。
簡単ですね。

次いで、CSSを記述します。

#grid {
  font-size: 24px;
  border: 1px solid black;
  width: 800px;
  height: 400px;
}

.item {
  background-color: rgba(150,0,0,0.2);
  border: 1px solid rgba(150,0,0,1);
  box-sizing: border-box;
}

#grid {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 100px 100px 100px 100px;
}

これでHTMLファイルをブラウザから確認してください。
黒い枠線の中に5つの赤いアイテムが表示され、1から4のアイテムは1行目に、5のアイテムは2行目にありますか?
正常に表示されなければHTMLとCSSの記述に間違いが無いか確認してください。

先のCSSで重要なのは2つ目の#gridの中身です。
1つ目の#gridと.itemはわかりやすいようにしているだけなので、説明は省きます。

まずは”display: grid;”で宣言します。
これによりCSS Gridを使用することを示しています。
次の

grid-template-columns: 200px 200px 200px 200px;

は#gridの列を200pxずつ4つに分割することを示します。
最後の

grid-template-rows: 100px 100px 100px 100px;

は#gridの行を100pxずつ4つに分割しています。
共に数を増やせばさらに分割することが可能です。
pxで指定しましたが、%やvh、vw、mm、emなどほとんどの単位が使用可能です。
さらにcalc()や後述するfrも使用できます。

今回はまだアイテムに位置を指定していなかったので、自動的に左上から敷き詰められていくので、先に説明したような配置になります。

では、アイテムの配置をしていきましょう。
.item1で説明します。

.item1 {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 2;
  grid-row-end: 4;
}

.item1が先ほどまで.item2があった場所の下に1列2行分表示されていれば正常です。
grid-column-startは列の開始箇所を示し、grid-column-endは列の終了箇所を示します。
この2つで.item1の幅を設定しています。
grid-row-startとgrid-row-endはそれが行に変わっただけです。
これらの配置はアイテムごとに設定できるため、重ねることも可能です。

なお、endがstartの値+1であるとき、省略しても表示されます。
上記ではgrid-column-endが省略可能です。

さらに、endは下記のように記述することができます。

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

このように書いても、先ほどまでと配置が変わりませんね。
spanを使用すると、列と行がそれぞれ開始地点から何個分の大きさを取るか指定することができます。

これまでの説明で、好きな大きさに分割し、好きな箇所に好きなサイズで配置できるようになったと思います。
分割個数を変えたりアイテムを好きなように配置してみたりしてください。

ショートハンド

さて、分割したり配置したりを繰り返すうち「もう少し楽に書きたい」と思ってきたことでしょう。
楽をしましょう。
ショートハンドを利用していきます。

#grid {
  display: grid;
  grid-template-columns: 200px repeat(3, 1fr);
  grid-template-rows: repeat(4, 1fr);
}

これは最初に分割を指定した書き方をより簡潔に書いたものです。
repeat()を説明する前に、frの説明をします。

frは前後で設定したサイズの残りを表します。
つまり、

#grid {
  width: 100px;
  grid-template-columns: 50px 1fr;
}

と書けば100pxのうち指定されているのは50pxのみなので、1frは残り全てになります。

#grid {
  width: 100px;
  grid-template-columns: 50px 1fr 1fr;
}

と書けば、frは合計で2あるので、1frは上の半分になります。
なお、frはlengthでないためcalc()で計算することはできないようです。

repeat()は指定サイズで指定回数分割するものです。
reaet(回数, サイズ)という指定をします。
先の例ではcolumnを200pxで1回と、repeat()を使って1fを3個作っています。
rowはさらに簡潔に、1frを4個、つまり4分割しています。
どちらも最初に指定した分割と同じ結果になります。

次は各アイテムです。

.item1 {
  grid-column: 2 /  3;
  grid-row: 2 / 4;
}

grid-column、grid-rowはそれぞれスラッシュ区切りで記述することでも範囲を指定できます。
“開始箇所 / 終了箇所”となります。
さらに、以下のようにして1つにまとめることができます。

.item1 {
  grid-area: 2 / 2 / 4 / 3;
}

やはりスラッシュ区切りで”行の開始箇所 / 列の開始箇所 / 行の終了箇所 / 列の終了箇所”と記述します。

最初に比べて、だいぶスッキリしてきたのではないでしょうか。
でも、まだ終わりではありません。
奥が深いです。

グリッドエリアに命名

次は#gridで分割した範囲に名前をつけ、各アイテムでそれを指定する方法です。
範囲に名前をつけるには、grid-template-areasを使用します。

#grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-template-areas: "position1  position2  position3  position4"
                       "position5  position6  position7  position8"
                       "position9  position6  position10 position11"
                       "position12 position13 position14 position15";
}

今回は4×4に分割しているので、合計で16個名前をつけます。
その際、行ごとにダブルクォーテーションで囲います。
複数のエリアにわたって指定したいときは、position6のように同じ名前をつけます。
この際、

  • ・間に別の名前を挟まない
  • ・同じ名前のエリアを見たとき、四角くなるようにする

必要があります。
つまり、以下の例は共にNGとなります。

/* position1が間に別の名前を挟んでる */
#grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-template-areas: "position1  position2  position1  position3"
                       "position4  position5  position6  position7"
                       "position8  position9  position10 position11"
                       "position12 position13 position14 position15";
}

/* position1の範囲が四角くない */
#grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-template-areas: "position1  position1  position2  position3"
                       "position1  position4  position5  position6"
                       "position7  position8  position9  position10"
                       "position11 position12 position13 position14";
}

各アイテムは、先ほど使用したgrid-areaで指定します。

.item1 {
  grid-area: position6;
}

grid-template-areasでエリアごとにを名前を設定する必要が出てきますが、どこに配置するのかを視覚的に確認できるようになります。

grid-template

最後にgrid-templateについて説明します。
gridのcolumnsとrowsはさらに簡潔に

#grid {
  display: grid;
  grid-template: repeat(4, 1fr) / repeat(4, 1fr);
}

とも書けます。
grid-templateは行列をスラッシュ区切りで”行の分割方法 / 列の分割方法”と書きます。
最初の頃にあれだけ書いていたのが嘘みたいに簡潔になりましたね。

さらにgrid-template-areasのように名前をつけることも可能です。

#grid {
  display: grid;
  grid-template: "position1  position2  position3  position4"  1fr
                 "position5  position6  position7  position8"  1fr
                 "position9  position6  position10 position11" 1fr
                 "position12 position13 position14 position15" 1fr
                / 1fr        1fr        1fr        1fr;
}

基本はgrid-template-areasのように書き、右端に行の高さを書きます。
そして、スラッシュで区切ってから列の幅を書いていきます。
これでgrid-template-columnsとgrid-template-rows、grid-template-areasをまとめることができました。

おまけ

最後に説明した”grid-template”は”grid”で書くこともできます。
ですが、両者には違いがあります。

基本形として、以下のように設定されているとします。

1
 
2
 
3
 
4
 
5
#grid {
  font-size: 24px;
  border: 1px solid black;
  width: 800px;
  height: 400px;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: auto;
  grid-template-areas: "a b"
                       "c d"
                       "e f";
  grid-auto-rows: auto;
  grid-auto-columns: auto;
  grid-auto-flow: column;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

この際の配置は下図のようになります。
2017-11-09_11h11_08

そこにgrid-templateを入れると、

#grid {
  display: grid;
  grid-template-columns: auto;
  grid-template-rows: auto;
  grid-template-areas: "a b"
                       "c d"
                       "e f";
  grid-auto-columns: auto;
  grid-auto-rows: auto;
  grid-auto-flow: column;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  grid-template: "a   b   c   d"
                 "e   f   g   h"
                 "i   j   k   l"
                 "m   n   o   p";
}

2017-11-09_11h11_40
上図のようになります。
grid-template-columnsとgrid-template-rows、grid-template-areasが無効化されていますね。

対してgridは

#grid {
  display: grid;
  grid-template-columns: auto;
  grid-template-rows: auto;
  grid-template-areas: "a b"
                       "c d"
                       "e f";
  grid-auto-columns: auto;
  grid-auto-rows: auto;
  grid-auto-flow: column;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  grid: "a   b   c   d"
        "e   f   g   h"
        "i   j   k   l"
        "m   n   o   p";
}

2017-11-09_11h11_58
同時に設定されたすべてのプロパティが無効化されます。
このように、”grid-template”と”grid”には無効化範囲が違います。
そのため”grid-template”と”grid”のどちらを使用するかは、無効化されるプロパティを考慮して決定するといいでしょう。
もちろん、各プロパティを”grid-template”および”grid”の下に書けばそちらが優先して反映されます。


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事