こんにちは。

キャスレーコンサルティングの向井と申します。

普段はJavaでの業務系Webアプリ開発に携わっておりますが、
前々からフロントエンドの製造が苦手だなあ、と感じておりました。

そんな中、「こんなのあるよ」と先輩に教えていただいた
CSS Grid Layoutがとても便利だったので、
自分の使用感なども織り交ぜつつご紹介します。

 

CSS Grid Layoutとは

CSS Grid Layoutは、画面を段組みするための仕組みで、
近年注目を浴びています。

以前はテーブルレイアウトや、floatプロパティを利用するレイアウトが主流でしたが、
これらは動作の遅さや、ブラウザによる表示の差異などが問題でした。

その後、Flexboxという仕組みが登場しましたが、
それでもレイアウトが崩れるケースもあり、使いどころを選ぶものでした。
そこで登場したのが、今までのレイアウトとは概念が異なるCSS Grid Layoutです。

 

二次元レイアウトのCSS Grid Layout

Grid Layoutでは、画面を格子状に区切って要素を配置していきます。

具体的には親要素としてコンテナを定義し、その中に子要素としてアイテムを配置します。

4本のラインで区切られた最小単位はグリッドセル、
1つ以上のグリッドセルで構成されている領域をグリッドエリアと呼び、
それぞれの間にギャップと呼ばれる余白を設定することができます。

CSS Grid Layoutによるレイアウト作成

実際にGrid Layoutで画面レイアウトを作成します。
先ほどの縦2×横3のレイアウト上に、3つのアイテムを配置するコードを作成します。

まず、HTMLは以下のようなものを用意します。


<html>
  <head><head>
  <body>
    <div id="container">
      <div class="grid1>grid1</div>
      <div class="grid2>grid2</div>
      <div class="grid3>grid3</div>
    <div>
  <body>
<html>

次にCSSを記述します。

以下のようにコンテナにgrid-template-rowsとgrid-template-columnsのプロパティを記述し、
縦は2、横は3のグリッドとして定義します。


#container {
  display: grid;
  grid-template-rows: repeat(2, 150px);
  grid-template-columns: repeat(3, 150px);
}

次にアイテムをコンテナに配置する記述ですが、これにはいくつか方法があります。

方法①グリッドのライン番号で指定

グリッドラインを指定する記述です。

先ほどのHTML内に定義したアイテムごとに、grid-column、grid-rowを設定します。
設定するには、アイテムを配置するエリアのライン番号を指定します。
今回のような縦は2、横は3のグリッドの場合は、下の図のようにラインの番号が割り振られます。

アイテムが占めるエリアに対応するラインの始点、終点をスラッシュ区切りで指定します。

例えば、先ほど定義したgrid2を、横は3から4、縦は1から3の位置に配置する場合は、
「grid-column: 3/4」「grid-row: 1/3」と記述します。

これらを踏まえて、以下のようにコーディングすると・・・


.grid1 {
  grid-column: 1/3;
  grid-row: 1;
  background-color: #FF69A3;
}

.grid2 {
  grid-column: 3/4;
  grid-row: 1/3;
  background-color: #75A9FF
}

.grid3 {
  grid-column: 1/3;
  grid-row: 2/3;
  background-color: #D0FF43;
}

結果は下の図のようになります。

方法②エリアに命名し配置する

次に配置するエリアに命名する方法です。

まずは、グリッド上で、どのアイテムが何という名前で使われるかを定義します。 「grid-area: エリア名」と記述すると、アイテムの配置を定義するgrid-template-areasで使用することができます。



.grid1 {
  grid-area: grid1;
  background-color: #FF69A3;
}

.grid2 {
  grid-area: grid2;
  background-color: #75A9FF;
}

.grid3 {
  grid-area: grid3;
  background-color: #D0FF43;
}

以下のように、コンテナにgrid-template-areasを記述し、
アイテムを配置したいエリアをスペース区切りで記述します。

2セル以上のエリアにひとつのアイテムを配置する場合は、
同様の名前を指定することで、その名前のエリアにひとつのアイテムとして配置されます。

個人的には、①の方法よりもこちらのほうが、
どのアイテムがどこに配置されるか視覚的にわかりやすいと感じました。


#container {
  display: grid;
  grid-template-rows: repeat(2, 150px);
  grid-template-columns: repeat(3, 150px);
  grid-template-areas: "grid1 grid1 grid2"
                       "grid3 grid3 grid2";
}

①と同様にアイテムが配置されました。

CSS Grid Layoutを使うメリット

ここまではGrid Layoutの基本的な情報をお伝えしましたが、
次は、Grid Layoutの良さについてお話しします。
(ここからは、私が使用してみて感じた主観的な内容になります)

メリット① ソースコードの可読性が高い

例えば、以下のようなレイアウトで画面を段組みするとしましょう。

テーブルレイアウトで作成すると、以下のようになりました。

※CSS


table {
  height: 600px;
  width: 450px;
}
div {
  border: 1.5px solid #eb6101;
}
.header {
  height: 150px;
  width: 450px;
}
.main {
  height: 150px;
  width: 150px;
}
.aside {
  height: 300px;
  width: 150px;
}

.nav {
  height: 300px;
  width: 150px;
}

.footer {
  height: 150px;
  width: 450px;
}

※HTML


<table>
  <tr>
    <td  colspan="3">
      <div class="header"></div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="nav"></div>  
    </td>
    <td>
      <div class="main"></div>
      <div class="main"></div>
    </td>
    <td>
      <div class="aside"></div>  
    </td>
  </tr>
  <tr>
    <td colspan="3">
      <div class="footer"></div>
    </td>
  </tr>
</table>

Grid Layoutで作成すると、以下のようになります。

※CSS

div {
  border: 1.5px solid #eb6101;
}
#container {
  width: 450px;
  display: grid;
  grid-template-rows: 150px 150px 150px 150px;
  grid-template-columns: 150px 1fr 1fr;
  grid-template-areas: "header header header"
                       "nav main1 aside"
                       "nav main2 aside"
                       "footer footer footer";
}
.header {
  grid-area: header;
}
.main1 {
  grid-area: main1;
}
.main2 {
  grid-area: main2;
}
.nav {
  grid-area: nav;
}
.aside {
  grid-area: aside;
}
.footer {
  grid-area: footer;
}

※HTML


<body>
  <div id="container">
    <div class="header"></div>
    <div class="main1"></div>
    <div class="main2"></div>
    <div class="nav"></div>
    <div class="aside"></div>
    <div class="footer"></div>
  </div>
</body>

このくらいの単純な画面構成ならば、大した問題にはなりませんが、
それでもGrid LayoutのほうがHTMLがすっきりしていると思いませんか?

HTMLで画面の要素を定義し、CSSで画面のデザインを定義しているため、
ソースコードをぱっとみて、どこで何が行われているかがわかりやすいかと思います。

HTML部分の記述が多い、ネストが深いなどが原因で、読みづらいと思うことがしばしばあったので、 ソースコードがすっきりとまとまるのは個人的に魅力を感じました。

メリット② レイアウトの修正・変更が簡単

先ほどの画面に新たにアイテムを追加する場合、
テーブルレイアウトでは、HTMLのテーブル全体に対して調整が必要なのに対し、
Grid Layoutでは、HTMLにはコンテナ内に新たに子要素を追加すればよいだけです。

※HTML


<body>
  <div id="container">
    <div class="header"></div>
    <div class="main1"></div>
    <div class="main2"></div>
    <div class="nav"></div>
    <div class="aside"></div>
    <div class="footer"></div>
    <div class="newItem">new item</div>     -- 新規で追加するアイテム
  </div>
</body>

※CSS


#container {
  width: 450px;
  display: grid;
  grid-template-rows: 150px 150px 150px 150px 150px;
  grid-template-columns: 150px 1fr 1fr;
  grid-template-areas: "header header header"
                       "newItem newItem newItem"    -- 追加アイテムの配置を定義
                       "nav main1 aside"
                       "nav main2 aside"
                       "footer footer footer";
}

.newItem {
 grid-area: newItem;
}

また、画面の構成を変更したい場合については、
テーブルレイアウトの場合は、新規で項目追加する際と同様にテーブルの調整が必要ですが、
Grid Layoutの場合、コンテナのCSSプロパティを修正するのみで、HTMLの修正は必要ありません。

例えば、画面左のnavを中央のmain1、main2と入れ替える場合は、以下の通りです。

※CSS


#container {
  width: 450px;
  display: grid;
  grid-template-rows: 150px 150px 150px 150px 150px;
  grid-template-columns: 150px 1fr 1fr;
  grid-template-areas: "header header header"
                       "main1 nav aside"  -- navとmain1、main2を入れ替える
                       "main2 nav aside"
                       "footer footer footer";
}  

余白を設定したい場合はギャッププロパティを設定します。

以下のようにCSSプロパティに記述することで、要素間に5pxの余白が生まれます。

※CSS


#container {
  width: 450px;
  display: grid;
  grid-template-rows: 150px 150px 150px 150px 150px;
  grid-template-columns: 150px 1fr 1fr;
  grid-template-areas: "header header header"
                       "nav main1 aside"
                       "nav main2 aside"
                       "footer footer footer";
  grid-gap: 5px;  -- 5pxの余白を設定
}  

読みやすく、修正・変更が加えやすいという点に加えて、
今まで多用していたテーブルレイアウトと比べ、とにかくコーディングが簡単でした。

特に、要素間の余白をとるギャッププロパティが簡単かつきれいに作れて、
一つの画面要素を調整すると他がずれる、といった「負の連鎖」がなく、
微調整にかかっていた時間を短縮することができました。

私がフロンサイドの製造が苦手だと感じていた理由の大部分が、
この「負の連鎖」による微調整に時間を取られすぎてしまうところだったので、
これが解消されるのはとてもありがたいことです。

既存の画面に対して頻繁に修正が入るプロジェクトでは、この技術は非常に有効だと思います。

ただ、ブラウザのバージョンによっては非対応の場合があるので、導入の前には一度ご確認ください。

まとめ

いかがでしたか。

効率的に画面レイアウトを組むにはCSS Grid Layoutは非常に有効な手段だと思いました。

レイアウト作成の際には、ぜひCSS Grid Layoutでの作成を検討してみてください。

以上、ご覧いただきありがとうございました。

向井 厚喜
CSVIT事業部 IT部 向井 厚喜
主に受託案件の開発業務を行ってます。