ここでは、有り得そうなデザインでfloat
だけでは対処が難しいような場面を想定して作った一例です。例えば以下のようなデザインの時。
PC版のデザイン
スマホ版のデザイン
HTMLを書いていく時は文書構造に基づいて書くべきですが、上記のような場合はスマホのレイアウトに基づいて書くと思います。つまり、「タイトル」→「画像」→「本文」→「注意書き」の順のHTMLになります。
ただ、この「注意書き」が曲者で、PCとスマホで微妙に位置が違います。PCのレイアウトを想定すると、「画像」→「注意書き」の順番の方がいいですが、レスポンシブなので縦に並んでいるスマホのレイアウトを優先して書いた方が楽です。
この時、PCのレイアウトにしようとすると、それぞれにfloatを左右に掛けて配置しようとします。
思惑
このようにすれば、PCのレイアウトのようになるはずです。
実際
一見、うまくいっているように見えますが、横幅を伸ばすと、
レスポンシブなので、横に文字が流れて画像より低くなった時にfloat
の回り込みが発生して、本文の下に来てしまいます。回り込まないように注意書きの横幅を100%
にすると、
今度は注意書きが画像の下にいかずにやっぱりうまくいきません。
結局、float
だけでは処理できず、calc()
やposition
などをガチャガチャと組み合わせれば実装できると思います。
そこでCSS 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
を活用したら、今までできなかったようなレイアウトも可能になるような気がするので、その可能性を追求したいです。