ザリガニデザインオフィス

こういう時に便利!Gridレイアウトの応用のサムネイル

こういう時に便利!Gridレイアウトの応用

ここでは、有り得そうなデザインでfloatだけでは対処が難しいような場面を想定して作った一例です。例えば以下のようなデザインの時。

PC版のデザイン
PC版のデザイン

スマホ版のデザイン
スマホ版のデザイン

HTMLを書いていく時は文書構造に基づいて書くべきですが、上記のような場合はスマホのレイアウトに基づいて書くと思います。つまり、「タイトル」→「画像」→「本文」→「注意書き」の順のHTMLになります。

ただ、この「注意書き」が曲者で、PCとスマホで微妙に位置が違います。PCのレイアウトを想定すると、「画像」→「注意書き」の順番の方がいいですが、レスポンシブなので縦に並んでいるスマホのレイアウトを優先して書いた方が楽です。

この時、PCのレイアウトにしようとすると、それぞれにfloatを左右に掛けて配置しようとします。

思惑
floatを使ってアプローチした図

このようにすれば、PCのレイアウトのようになるはずです。

実際

デモはこちら

一見うまくレイアウトできている図
一見、うまくいっているように見えますが、横幅を伸ばすと、

注意書きのレイアウトが崩れた図

レスポンシブなので、横に文字が流れて画像より低くなった時にfloatの回り込みが発生して、本文の下に来てしまいます。回り込まないように注意書きの横幅を100%にすると、

注意書きのレイアウトが崩れた図

今度は注意書きが画像の下にいかずにやっぱりうまくいきません。

結局、floatだけでは処理できず、calc()positionなどをガチャガチャと組み合わせれば実装できると思います。

そこでCSS gridの出番

デザインを以下のようなグリッドに区切ります。

gridの指定の図

CSSグリッドについての細かい説明はこちらに詳しく書かれています。

参考:Qiita CSS Grid Layout を極める!(基礎編)

以下のようなCSSを設定します。

.wrapper {
  display: grid;
  grid-template-rows: 40px auto 1fr;
  grid-template-columns: auto 1fr;
}

1列目と2行目をautoにしたのは画像のサイズに合わせるためです。今回は500pxなので上の画像のようにpxを決め打ちでもいいですが、仮に画像の大きさが変わった時のため、あるいは可変にするためにautoに指定しています。

.ttl {
  grid-row: 1/2;
  grid-column: 2/3;
}

.img {
  grid-row: 1/3;
  grid-column: 1/2;
}

.img img {
  display: block;
  width: 500px;
  height: 500px;
}

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

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

画像、タイトル、本文、注意書きを上記のように設定し、グリッドに合わせます。これでデザインの意図したようになります。

デモはこちら

別にわざわざgridでやる必要もなくない?

確かに、上記の例ではpositionなど既存CSSを使えば実装は可能です。ただ、gridを使うと、画像の大きさが変わったときにも自動的に対応してくれます。positionだと決め打ちしないといけないので、その点不便です。(個人的にpositionでレイアウトを組むのは負けかなと思っています。)

PC用とスマホ用で「注意書き」を2つ書けば良くない?

PCとスマホで両方用意し、pc_showなどのクラスで表示を切り替える技もあります。ただ、その場合HTMLに2つ「注意書き」が存在し、文書構造としてよろしくないと思います。HTMLは文書構造を示すものであり、デザインやレイアウトのためにHTMLの文書構造をいじるのは、出来る限り避けたいところです。

gridの可能性

ここでは有り得そうなデザインシチュエーションでgridを実践的に使ってみました。かつてのテーブルレイアウトのようですが、gridの可能性は単に格子状や要素をタイル状に並べるだけでなく、レイアウトに自由度を与えられる点ではないでしょうか。

つまり、HTMLの文書構造を維持したまま、それとは独立にレイアウトが組め、なおかつレスポンシブにも対応できるところが肝だと思います。positionも確かにレイアウトの自由度はありますが、硬直的で変化に弱いです。その点、gridは柔軟に対応できるので可能性を感じます。

gridを活用したら、今までできなかったようなレイアウトも可能になるような気がするので、その可能性を追求したいです。