CodeCode

なんか色々おぼえ書き。だいたいweb制作関連。

CSS Grid Layout Module(IE対応)

CSS Grid Layout Moduleとは

CSS3で策定が進められている、Flexible Box Layout Moduleに次ぐ新たなレイアウトモジュール。 コンテナを縦横の格子状に分割して要素を自由にレイアウトできます。

ブラウザの実装状況

IE・Edgeが完全には対応してないものの、基本機能は最新ブラウザで実装されています。
https://caniuse.com/#search=Grid%20Layout
Can I Use: https://caniuse.com/#search=Grid%20Layout

こんな感じのレイアウトをする場合を例に、プロパティの説明をしていきます。

実装

<div class="container">
    <div class="item item_header">header</div>
    <div class="item item_nav">nav</div>
    <div class="item item_main">main</div>
    <div class="item item_sidebar">sidebar</div>
    <div class="item item_footer">footer</div>
</div>

HTMLはこのようになっています。

.container{
    display: grid;
    display: -ms-grid;
}

これでコンテナがグリットレイアウトの状態になります。

.container{
    display: grid;
    display: -ms-grid;

    grid-template-columns: 100px 1fr 100px;
    grid-template-rows: auto auto auto;
}

grid-template-columns で、列のサイズを指定します。 この例だと、幅が100pxの列、auto(親の幅に合わせて変動)の列、もうひとつ100pxの列ができます。 grid-template-rows で、行のサイズを指定します。 この例だと、列と同じように高さが30pxの行、auto(親の幅に合わせて変動)の行、もうひとつ100pxの行ができます。

ブラウザで見るとこんな状態に、IE11ではどうかというと

はい。予想通りです。さすがIE。 一筋縄ではいかない。

-ms-grid-columns: 100px 1fr 100px;
-ms-grid-rows: auto;

IE11ではこのプロパティを使います。 -ms-grid-columnsgrid-template-columnsと同じように列のサイズを、-ms-grid-rowsgrid-template-rows と同じように行のサイズを指定します。

ちょっと伸びた気がする。 要素の配置をしていきます。 HeaderFooterを横いっぱいに伸ばします。

.item_header, .item_footer{
    grid-column: 1 / 4;
}

grid-columnでカラムのサイズを指定します。 あたいは1÷4? ではなく、グリッドの1番から4番までを意味します。

ブラウザでみてみるとちゃんと思った通りの形になっています。

IE11では

はい。 では、IE用の記述もしておきます。 ただ、ここで注意が必要なのはIEはプロパティだけでなく、グリッドの考え方も違います。

.item_header{
    -ms-grid-column: 1;
    -ms-grid-row: 1;
    -ms-grid-column-span: 3;

    grid-column: 1 / 4;
}

-ms-grid-columnは列の位置、-ms-grid-rowは行の位置、-ms-grid-column-spanは結合するセルの個数を指定します。 grid-columnは1番目から4番目となっていましたが、IEでは1番と1番になっています。 これは上にも書いたように、グリッドの考え方が違うからです。
1番目の列のセルと1番目の行のセルに置いて、3つのセルを結合させるので、このような指定になります。

-ms-grid-column: 1;
-ms-grid-row: 1;
-ms-grid-column-span: 3;

Headerと同じくFooterにも同じように指定していきます。 Footerは1番目の列のセルと3番目の行のセルに置いて、3つのセルを結合させるので,

.item_footer{
    -ms-grid-column: 1;
    -ms-grid-row: 3;
    -ms-grid-column-span: 3;

    grid-column: 1/4;
}

こうなります。 IEで見てみると、
残念ながらこうなります。 他の要素にも位置を指定してやらなければなりません。

.item_nav{
    -ms-grid-column: 1;
    -ms-grid-row: 2;
}

.item_main{
    -ms-grid-column: 2;
    -ms-grid-row: 2;
}

.item_sidebar{
    -ms-grid-column: 3;
    -ms-grid-row: 2;
}


これで両方のブラウザが思った通りの記述になりました。

アスキーアートみたいに指定

この記述はIEには対応していませんが、Google ChromeやFirefoxでは対応している指定方法です。 通常は

grid-column: 1 / 4

と指定していましたが、もっと目で見てわかりやすい指定ができます。 まずは、grid-areaで各要素に名前をつけます。

.item_header{grid-area: header;}
.item_nav{grid-area: nav;}
.item_main{grid-area: main;}
.item_sidebar{grid-area: sidebar;}
.item_footer{grid-area: footer;}

grid-template-areasでこのように指定していきます。

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

    grid-template-areas:
        "header header header"
        "nav main sidebar"
        "footer footer footer";
}

3行3列のグリッドなので、横いっぱいの**headerは、3つ書きます。 nav, main, sidebarはそれぞれ、2行目にいるので1つづつ書きます。 最後にfooterも3行目いっぱいに広がるので、headerを3つ書きます。 grid-template-areas は見てそのまま、まるでアスキーアートのようにグリッドアイテムを配置することができます。 grid-template-areas を使ったレイアウトの方が直感的でわかりやすいですね。

fr

grid-template-columnsで使われているfr は相対単位で、利用可能な空間の割合を示します。

.container{
    grid-template-columns: 1fr 2fr 1fr;
}

この例だと、各グリッドアイテム間の割合がそれぞれ1:2:1となります。

repeat

grid-template-columnsgrid-template-rows のが同じ値の繰り返しの場合 repeat を使い省略して書くことができます。

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

この場合、 100px auto と 30px auto が繰り返されているので repeat を使って書くと

.container{
    grid-template-columns: repeat(2, 100px auto) 100px;
    grid-template-rows: repeat(2, 30px auto) 30px;
}

このように書くことができます。  

Autoprefixerについて

autoprefixer 8.1、gulp-autoprefixer@5.0でIE用のプロパティが出力されるようになりました。

使い方は簡単で、

.pipe(autoprefixer({
  browsers: [
    'last 2 versions'
  ],
  grid: true,
  cascade: false
}))

grid: trueを入れるだけです。 上で使ったコードをAutoprefixerにかけると、

.container{
    display: grid;

    grid-template-columns: 100px 1fr 100px;
    grid-template-rows: auto auto auto;
}

.item_header, .item_footer{
    grid-column: 1 / 4;
}

こうなります。

.container {
  display: -ms-grid;
  display: grid;

  -ms-grid-columns: 100px 1fr 100px;
  grid-template-columns: 100px 1fr 100px;

  -ms-grid-rows: auto auto auto;
  grid-template-rows: auto auto auto;
}

.item_header,
.item_footer {
  -ms-grid-column: 1;
  -ms-grid-column-span: 3;
  grid-column: 1/4;
}

当たり前ですが、navやmain,sidebarの個別の位置までは補完してくれません。 なのでIE11での表示もこうなってしまいます。
しかし、後に説明したgrid-template-areasを使うと、

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

    grid-template-areas:
        "header header header"
        "nav main sidebar"
        "footer footer footer";
}

.item_header{grid-area: header;}
.item_nav{grid-area: nav;}
.item_main{grid-area: main;}
.item_sidebar{grid-area: sidebar;}
.item_footer{grid-area: footer;}

上のコードをAutoprefixerにかけると、

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

.item_header {
	-ms-grid-row: 1;
	-ms-grid-column: 1;
	-ms-grid-column-span: 3;
	grid-area: header;
}

.item_nav {
	-ms-grid-row: 2;
	-ms-grid-column: 1;
	grid-area: nav;
}

.item_main {
	-ms-grid-row: 2;
	-ms-grid-column: 2;
	grid-area: main;
}

.item_sidebar {
	-ms-grid-row: 2;
	-ms-grid-column: 3;
	grid-area: sidebar;
}

.item_footer {
	-ms-grid-row: 3;
	-ms-grid-column: 1;
	-ms-grid-column-span: 3;
	grid-area: footer;
}

grid-template-areasから各grid-areaの位置も補完してくれます。

まとめ

CSS Grid Layout Moduleの基本的な部分について書きました。 基本部分はもう実装されているのでぜひ使ってみてください。 ただ、IE・Edgeにはベンダープレフィックス( -ms- )が必要だったり、プロパティが違ったりとIE・Edgeに対応させるには記述量が増えてしまします。 Autoprefixerを使えば、grid-template-areasでわかりやすく記述できるし、他の要素の位置も補完されるので、通常の書き方よりはgrid-template-areasの方がおすすめです。

TOPへ戻る