2021.01.05

  • CSS

CSSグリッドレイアウト入門!基本的な使い方と解説

CSSによるレイアウトの構築はflexboxを主に使用していましたが、flexboxでは再現が難しい複雑なレイアウトに対応できるGrid Layoutの魅力にはまってしまったので、今回はその入門となる簡単な使用方法を解説していきます。

グリッドレイアウトを構成するコンテナ(親)とアイテム(子)の関係

グリッド全体を囲うコンテナを親として、コンテナの子要素としてアイテムを配置していきます。flexboxよりも便利な点としては高さの異なるコンテンツなどの単純な横並びではない複雑なレイアウトにも対応しています。

グリッドレイアウトの概要

次に紹介するプロパティの部分とも関係しますが、レイアウトの基本的な考え方として、グリッドのX軸をrow、Y軸をcolumnとして、各アイテムの境界ごとにラインで区切って軸を決めていきます。

グリッドレイアウトであれば上の図のように横幅いっぱいに広がったheader、footerと横並びになったmainとsideも含めてレイアウトを構築できます。

基本的なプロパティ

上記のようなレイアウトの構築を例に各プロパティの紹介をしていきます。

HTMLの記述はシンプルに

<div class="container">
    <header class="header">header</header>
    <main class="main">main</main>
    <aside class="sidebar">sidebar</aside>
    <footer class="footer">footer</footer>
</div>

基本的にはコンテナとなる要素と、そのなかにアイテムとして配置する要素が記述されていれば問題ありません。

コンテナ用のCSS

.container {
  display: grid;
}

display: grid;がグリッドレイアウトの基本です。
次に各グリッドのサイズを指定していきます。

.container {
  display: grid;
  grid-template-rows: 100px auto 100px;
  grid-template-columns: auto 100px;
}

grid-template-rowsがグリッドの横方向のサイズを指定し、grid-template-columnsが縦方向のサイズを指定しています。
上記の図ではrowの方向にグリッドが3つ、columnの方向にグリッドが2つ分割されているので、分割する数に応じて数値を指定していきます。
autoを指定すると、アイテムの量に応じて自動的にサイズを調整してくれます。

次にこの指定した数値をもとに、コンテナ内のアイテムに表示位置を指定していきます。

アイテム用のCSS

.container {
  display: grid;
  grid-template-rows: 100px auto 100px;
  grid-template-columns: auto 100px;
  .header {
    grid-row: 1 / 2;
    grid-column: 1 / 3;
  }
  .main {
    grid-row: 2 / 3;
    grid-column: 1 / 2;
  }
  .sidebar {
    grid-row: 2 / 3;
    grid-column: 2 / 3;
  }
  .footer {
    grid-row: 3 / 4;
    grid-column: 1 / 3;
  }
}

先ほどのCSSの続きになります。
コンテナ内のアイテムにはgird-rowgrid-columnで位置を指定していきます。
何やら不明な数字が並んでいますが、意外と単純。.headerの記述を見ていきましょう。
grid-rowの1 / 2という数値は、上の図のrow1からrow2、横に伸びる線の1番目から2番目までを領域として指定しています。
同様にgrid-columnは縦に伸びる線の1番目から3番目までを指定します。他のアイテムも同様にレイアウトに乗っ取って位置を指定していきます。

これにより以下のようなレイアウトが構築できます。

ちなみにgrid-row:1 / 2;のように隣り合う数値を指定する場合には、grid-row:1;のように省略ができます。例えば先ほどの例でいうと、下記のようになります。

.header {
  grid-row: 1;
  grid-column: 1 / 3;
}
.main {
  grid-row: 2;
  grid-column: 1;
}
.sidebar {
  grid-row: 2;
  grid-column: 2;
}
.footer {
  grid-row: 3;
  grid-column: 1 / 3;
}

また、数値で指定するのが面倒な場合にはgrid-template-areasを活用しましょう。このプロパティはコンテナ側で表示する各領域に名前を指定し、その名前をアイテム側で振ります。

.container {
  display: grid;
  grid-template-rows: 100px auto 100px;
  grid-template-columns: auto 100px;
  grid-template-areas:
    "header header"
    "main sidebar"
    "footer footer";
}

上記のコードではheaderを2回繰り返しています。レイアウト上ではheaderは分割されていなくてもグリッド上ではgrid-template-columnsで分割されているため、その領域分エリア名を繰り返しています。

アイテムのCSSは以下のようになります。

.header {
  grid-area: header;
}
.main {
  grid-area: main;
}
.sidebar {
  grid-area: sidebar;
}
.footer {
  grid-area: footer;
}

CSSでアイテムの並び順番を指定しているため、HTMLの記述順とは異なる配置も可能になります。改めて基本的な流れをおさらいしましょう。

  • 大枠となるコンテナと配置するアイテムをhtmlで記述
  • 親要素となるコンテナにdisplay:gridgrid-template-rowsgrid-template-columnsを指定してサイズを決める
  • 子要素となるアイテムにgird-rowgrid-columnで位置を決める

余白を定義するgap

先ほどの作例では各アイテムが密接に並べられたレイアウトを組みましたが、各要素間の余白もコンテナに指定することができます。
使用するプロパティはrow-gapcolumn-gapです。

.container {
  display: grid;
  row-gap: 10px;
  column-gap: 10px;
}

rowとcolumnで別々に余白を指定していますが、縦横ともに同じ余白の場合にはふたつを省略して以下のようにも記述できます。

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

fr単位(fraction)

これまでの内容でも十分グリッドレイアウトとして機能しますが、横幅や高さなどをpxで指定していると、ブラウザサイズに柔軟に対応したいときに不便です。
fr単位(fraction)とはグリッドで用意された単位で、特にサイズを指定したくない、コンテンツ量に応じて柔軟に対応させたい場所などに活用できます。

.container {
  display: grid;
  grid-template-columns: 100px 1fr 100px;
}

タイルレイアウトで構築したい場合

カード型のコンテンツを並べたタイルレイアウトのような、ブラウザの幅に応じてサイズを調整したいようなコンテンツの配置にもfr単位は有効です。

CSSのコードは下記のようになります。
grid-template-columnsと一緒にgapも指定します。

.container {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: 20px;
}

repeatは文字通り繰り返しの処理になります。ここでは1frのサイズで3つ並べるという記述になります。なお、コンテンツが3つ以上ある場合には、4つ目から自動的に折り返して配置されるようになります。

レスポンシブデザインで構築する

グリッドレイアウトで組んだコンテンツをレスポンシブに対応させるやり方として、簡易的な方法ではメディアクエリーでgrid-templateを書き換える方法があります。

CSSは先ほどと同じものを例に使います。

.container {
  display: grid;
  grid-template-rows: 100px auto 100px;
  grid-template-columns: auto 100px;
  grid-template-areas:
    "header header"
    "main sidebar"
    "footer footer";
  .header {
    grid-area: header;
  }
  .main {
    grid-area: main;
  }
  .sidebar {
    grid-area: sidebar;
  }
  .footer {
    grid-area: footer;
  }
}

ブレイクポイント時の対応はシンプルに済むよう、コンテナに記述したgrid-templateのrows,columns,areasのみに記述を追加します。

@media screen and (max-width: 768px) {
  .container {
    grid-template-rows: 100px auto auto 100px;
    grid-template-columns: auto;
    grid-template-areas: 
    "header"
    "main"
    "sidebar"
    "footer";
  }
}

レスポンシブのブレイクポイントのタイミングで横並びだったアイテムを縦一列の1カラムに可変しています。そのため、grid-templateのrowsは4段に、columnsは1段になりましたので、それぞれ数値を変更。
areasに関しても縦列1段に変更になったので、並び順のまま修正を加えていきます。

まとめ

flexboxに慣れ親しんでいた自分にとっては、記述の仕方などで戸惑う部分もありましたが、グリッドレイアウトのそもそもの考え方が他のレイアウト方法と違うんだなと、理解できてくると慣れるのも早いかと思います。(そういう私も実務案件では、あまり試せていませんが…)

最後にGrid LayoutがほかのFlexboxやtableと、どのように違うのか簡単にまとめましたので紹介します。

Flexboxとの比較

Flexbox(正式名:Flexible Box Layout Module)とGrid Layoutとの違いとして“次元”が違うと言われます。
Grid Layoutoが2次元的で、これまでにみたように縦横自由にコンテンツを配置できます。
それに対してFlexboxは1次元的といわれ、基本的には1方向でコンテンツを配置していきます。

tableとの比較

単純にレイアウトを組むだけであればtableタグでも似たようなものは作れますが、tableがhtmlでの構造をベースに考えられたものだとすれば、Grid Layoutはhtmlのアウトラインによらず、cssをベースに考えられたものだと言えます。そのため、<header><main><footer>といったタグに対しても自由に構築することが可能です。

参考サイト
https://www.itti.jp/web-design/quick-css-grid/
https://qiita.com/kura07/items/e633b35e33e43240d363

Share

お問い合わせ

このブログではデザインやWEBに関するHow toなどをご紹介しています。ブログ記事についてのお問い合わせはこちらからお願いします。