はじめに
「HTML&CSSは簡単」と言われます。ところが、いざWebの実装・構築を始めてみると、いろいろな壁にぶつかります。
- レイアウトのためにどんどん深くなるDOM(HTML)のネスト構造
- スペースをどこでどう入れていくか
- どうやってレスポンシブを管理するか
- コンポーネントを組み込んだときの影響をどう軽減していくか
… etc. 悩みのタネは尽きません。
それもそのはず。CSSは「ドキュメントをレイアウトするために作られたもの」であり、現在のWebのように多種多様なものをレイアウトしたり、コンポーネント化して管理するといったことは想定されていなかったからです。
そんな中、ドキュメント以外の、さまざまなレイアウトに対応すべく登場したのが、新しいレイアウトシステムの「CSSグリッド(CSS Grid)」です。
ただ、これまでのCSSの機能の1つとして捉えてしまうと、なかなかグリッドのポテンシャルを活かすことができません。そこで本書では、HTML & CSSの歴史から振り返り、CSSグリッドの立ち位置や基本を見直した上で、実践的なパーツやUIを構築していきます。
" CSSグリッドでWebのレイアウトをロジカルにコントロールする "
そのための一助として、本書を活用していただければ幸いです。
CSSグリッドの立ち位置と本書の構成
「フレックスボックスは1次元、CSSグリッドは2次元のレイアウトに適している」と言われることから、比較されることの多い2つのレイアウトモデルです。この比較、CSSグリッドへの取っ掛かりとしては悪くないのですが、フレックスボックスを主体とした比較であるため、CSSグリッドの本質が分かりづらくなってしまうという問題を抱えています。
では、何が問題なのでしょうか? CSSグリッドの立ち位置を考えれば、その比較の対象はフローレイアウトとされるべきなのです。そう、Webのレイアウトの根本であるフローレイアウトです。

フローレイアウトはドキュメントのレイアウトシステムとしてWebの誕生とともに登場したレイアウトシステムです。Webでレイアウトする際に何も設定しなければ、デフォルトでフローレイアウトが使用されます。そのため、意識されることもほとんどありません。
ただ、フローレイアウトを意識すると、フレックスボックスはフローレイアウトを拡張した存在であることが見えてきます。そして、CSSグリッドはフローレイアウトの抱える問題を解決するために用意された、まったく異なるレイアウトシステムであることも。
そのため、「フレックスボックスは1次元、CSSグリッドは2次元のレイアウト」という形で比較しても、見えてこない部分がたくさんあります。その見えてこない部分を明確にしないと、CSSグリッドの必要性や重要性はいまいちピンときません。「CSSグリッドを使わなくてもフレックスボックスでもできるし…」「少ない行数で書けるなら使うけど…」ぐらいの扱いになってしまいます。
何しろ、現在のWebデザインはフローレイアウトで実現可能なものをベースにして進化してきたものです。ここまでのHTML&CSSでの蓄積が元になっていますので、当然です。
そして、そうしたデザインを扱う限り、フローレイアウトのレイアウトシステムに問題を感じることはありませんし、フローレイアウトを使ってレイアウトする方が効率的でもあります。CSSグリッドの必要性をあまり感じないのも当然のことと言えます。

フローレイアウトに最適化されたレイアウト
ところが、フローレイアウトが苦手とするものが徐々に増えてきました。たとえば、WebアプリのUIのように、レスポンシブな環境できっちりとレイアウトをコントロールしなければならないもの。また、ヘッドレスCMSからのコンテンツやコンポーネントが抱えることになる子要素、想定しきれない要素のスタイリングなど…。

構築していくレイアウト
こうしたレイアウトは、ドキュメントのためのレイアウトシステムとして登場したフローレイアウトがまったく想定していなかったものですから仕方がありません。そして、フローレイアウトの代わりに、こうしたものも扱えるレイアウトシステムとして登場したのがCSSグリッドなのです。
そこで、本書では実際にCSSグリッドのコードを扱い始める前に、CSSグリッドの立ち位置やその構成を明確にしておきたいと思います。
そのためにはWebにおけるレイアウトシステムの歴史や背景を知るのが近道です。Chapter 1と2を通してフローレイアウトの背景や拡張の歴史、CSSグリッド誕生までの流れや、CSSグリッドに搭載されることになった各種機能の必然性や特徴などを見ていきます。
Chapter 3からはサンプルを構築しながらCSSグリッドの基本やロジックを確認し、Chapter 5で実践的なレイアウトを構築していきます。
Chapter 1 Web標準のレイアウトシステム

Webが誕生したときから使われてきた、標準のレイアウトシステムである「フローレイアウト」。その生い立ちから、どうしてフローレイアウトでレイアウトを制御するのは難しいのか、ハックを使ったレイアウトの普及などについて見ていきます。
Chapter 2 CSSグリッドの誕生とその特徴

フレックスボックス(Flexbox)が登場したものの、それでは不十分だった理由。そして、フローレイアウトやフレックスボックスとは異なるものとして、どのような概念を取り込み、どのような特徴を持つ形で「CSSグリッド」が登場したのかを見ていきます。
Chapter 3 基本のグリッド
CSSグリッドに取り入れられた概念を元に、3タイプのグリッド「トラック」「ライン」「テンプレート」を構築します。作業を通して、CSSグリッドの基本的な使い方や主要機能も確認していきます。

Chapter 4 CSSグリッドのロジック
グリッドの行列の生成、アイテムの配置、トラックサイズの確定といった処理がどのように行われるのか、positionやアニメーションを併用するとどうなるのかなど、CSSグリッドのロジックを掘り下げます。処理を理解する上で必要になる「CSSにおけるサイズの基本」についてもまとめていますので、参考にしてください。
Chapter 5 グリッドレイアウト実践
CSSグリッドを活用して、実践的に各種レイアウトを構築します。メニューやカードといった細かな UIパーツから構築し、それらを組み合わせて次のようなレイアウトを形にしていきます。

もくじ
- Chapter 1 Web標準のレイアウトシステム(フローレイアウト)
- 1.1 Web標準のレイアウトシステム —— フローレイアウトの生い立ちと基本
- Webが誕生したときからWebの表示はフローレイアウト
- 要素ごとにスタイルを設定
- ■ Tips: ドキュメント構造とレイアウトの分離
- 要素の相互関係で配置が決まる
- 初期状態の要素の設定はブラウザのCSSで決まる
- ■ Tips: UAスタイルシートの指針
- フローレイアウトのルール
- 1.2 フローレイアウトでレイアウトを制御するのは難しい
- フローレイアウトの限界
- 1.3 ハックを使ったレイアウトの登場
- ■ Tips: フローレイアウトを制御しやすくするために生まれたもの(1)―― リセットCSS
- ■ Tips: フローレイアウトを制御しやすくするために生まれたもの(2)―― CSSフレームワーク
- ■ Tips: フローレイアウトを制御しやすくするために生まれたもの(3)―― フクロウセレクタ
- ■ Tips: フローレイアウトを制御しやすくするために生まれたもの(4)―― ユーティリティクラスベースのCSSフレームワーク(Tailwind CSSなど)
- 参考文献
- 1.1 Web標準のレイアウトシステム —— フローレイアウトの生い立ちと基本
- Chapter 2 CSSグリッドの誕生とその特徴
- 2.1 ハックを使わないレイアウトのはじまり
- CSSの機能の分割
- レイアウト用の新しいモジュールの登場
- ■ Tips: Intrinsic Web Design ―― ハックを使わないレイアウトの考え方
- 2.2 フレックスボックスレイアウトの登場
- フレックスボックスの特徴
- 2.3 フローレイアウトとフレックスボックスでは不十分だったレイアウト制御
- フローレイアウトでは不十分だった理由
- フレックスボックスでも不十分だった理由
- 2.4 CSSグリッドレイアウトの登場
- CSSグリッドの仕様化のきっかけ
- CSSグリッドに取り入れられた概念
- ■ Tips: CSSグリッドのブラウザへの実装を後押ししたもの
- ■ Tips: 仕様の策定過程で求められる実装と相互運用性について
- 2.5 CSSグリッドのベースとなっている概念
- トラック
- ライン
- テンプレート
- ■ Tips: グリッドシステムとは
- 2.6 CSSグリッドで構築するグリッドとレイアウトの特徴
- グリッドを介した配置のコントロール
- 要素の自動配置
- グリッドの自動生成
- レスポンシブを含めたレイアウトについての新しい考え方が要求される
- 2.7 2つのレイアウトシステム
- 2.8 CSSグリッドを活用するために
- ■ Tips: displayのマルチキーワード構文(2値構文)
- 2.1 ハックを使わないレイアウトのはじまり
- Chapter 3 基本のグリッド
- 3.1 グリッドを構成するもの
- 3.2 3タイプのグリッドでテキストと画像を並べる
- 3タイプのグリッドの違い
- 3.3 基本のグリッド ―― ライン
- ラインを使ってグリッドを構成する
- ■ Tips: ライン名をつける
- ■ Tips:行・列のガターを個別に指定する
- ラインを使ってアイテムを配置する
- ■ Tips: 「配置を終了するライン番号」の指定を省略する
- ■ Tips:「配置を開始・終了するライン番号」を個別に指定する
- ■ Tips: ライン名で配置を指定する
- レスポンシブでレイアウトを変える
- 3.4 基本のグリッド ―― トラック(カラム)
- トラックを使ってグリッドを構成する
- トラックを使ってアイテムを配置する
- ■ Tips: 「どこから」のトラック数なのかを指定する場合
- レスポンシブでレイアウトを変える
- 3.5 基本のグリッド ―― テンプレート(エリア)
- エリアを使ってグリッドを構成する
- ■ Tips: セルにエリア名を割り当てない場合
- ■ Tips: エリアとトラックサイズをまとめて指定する
- エリアを使ってアイテムを配置する
- ■ Tips: エリア名とライン名とアイテムの配置
- レスポンシブでレイアウトを変える
- ■ Tips:grid-areaで行・列の配置先をまとめて指定する
- ■ Tips: gapが指定するガターについて
- Chapter 4 CSSグリッドのロジック
- 4.1 グリッドの行列を生成する処理
- スペースがない場合の処理
- 暗黙的なグリッドのトラックサイズ
- ■ Tips: 暗黙的なトラックサイズは繰り返し適用される
- 4.2 グリッドアイテムを配置する処理
- 配置のステップ
- 空きスペースを埋めるように自動配置する場合
- 列を埋めるように自動配置する場合
- 配置先が重複する場合
- トラックに対するアイテムの位置揃え(配置)とサイズ
- ■ Tips: 横方向と縦方向のアイテムの位置揃えをまとめて指定する
- 4.3 CSSにおけるサイズの基本(1)――ブロック要素のサイズ
- サイズを指定するプロパティ
- フローレイアウトでのブロック要素のサイズ
- 中身の高さ
- 4.4 CSSにおけるサイズの基本(2)――インライン要素のサイズ
- フローレイアウトでのインライン要素のサイズ
- line-heightで行ボックスの高さをコントロール
- ■ Tips: line-heightのリセット
- 複数行になった場合
- 4.5 CSSにおけるサイズの基本(3)――ブロック要素の中身の高さ
- 中身がインラインレベル要素のみで構成されている場合
- ■ Tips: リセットCSSに含まれる画像の下の余白を削除する設定
- 中身がブロック要素のみで構成されている場合
- 中身がブロック要素とインラインレベル要素で構成されている場合
- 4.6 トラックサイズを決める処理
- トラックサイズ
- トラックサイズが確定されるステップ
- すべてがautoなときのトラックサイズ
- グリッドコンテナでのトラックの位置揃え(配置)とトラックサイズ
- ■ Tips: 横方向と縦方向のトラックの位置揃えをまとめて指定する
- 4.7 ネストしたグリッドとサブグリッド
- ネストしたグリッドでコントロールする場合
- サブグリッドでコントロールする場合
- サブグリッドの特徴
- 4.8 position: absoluteによる絶対位置指定とグリッド
- グリッドアイテムの絶対位置が確定されるステップ
- 自動配置されるアイテムにposition: absoluteを適用した場合
- 明示的に配置先を指定したアイテムにposition: absoluteを適用した場合
- オフセットを指定しなかった場合の包含ブロックとjustify-self / align-self による位置揃え
- サブグリッドのアイテムを親のグリッドに配置する
- 4.9 アニメーションとグリッド
- ■ Tips: autoのトラックに可変サイズの画像を配置したときのトラックサイズ
- 4.1 グリッドの行列を生成する処理
- Chapter 5 グリッドレイアウト実践
- 5.1 構築するレイアウト
- レイアウトの構成パーツ
- 5.2 スタックレイアウト(縦並び・横並び)
- 縦並び
- 横並び
- ■ よくあるトラブル: グリッドアイテムの間隔が広がる
- ■ よくあるトラブル: ボタンのマークアップによってグリッドの高さが変わる
- 5.3 アイコン付きリンクとボタン
- アイコンとテキストを縦に並べる
- アイコンとテキストを横に並べる
- ■ よくあるトラブル: ボタン内で横並びにしたアイコンとテキストの間隔が広がる
- アイコン付きリンクを縦並びにしたメニュー
- アイコン付きリンクを横並びにしたメニュー
- 5.4 検索フォーム
- 入力欄の横にアイコンボタンを配置
- 入力欄の中にアイコンボタンを入れる
- ■ よくあるトラブル: 配置を指定したはずのアイテムが重ならない
- 5.5 ヘッダー
- 5.6 メインビジュアルとセクション
- 縦並び
- ■ よくあるトラブル: テキストが中央揃えにならない
- 横並び(画像の高さを横に並べたアイテムに揃える)
- ■ よくあるトラブル: 画像の高さが横に並べたアイテムに揃わない(画像によって行の高さが引き伸ばされる)
- 重ね合わせ(画像にアイテムを重ねる)
- 5.7 カード
- 縦並び(画像を上に配置する)
- 横並び(画像を横に配置する)
- 重ね合わせ(画像にアイテムを重ねる)
- ■ よくあるトラブル: パディングで挿入した余白部分もグリッドの行列として使う場合(position: absoluteとグリッドの組み合わせ)
- 5.8 データカード
- 四隅にデータを配置する
- 下部を大きく使う
- 5.9 カードUI(グリッドビューレイアウト)
- グリッドコンテナの幅に応じて自動的に列の数を変える
- 5.10 カードUI(Bento UI)
- コンテナクエリでグリッドコンテナの幅に応じてカードサイズを変える
- ■ よくあるトラブル: グリッドにマッチしないアイテムを置いた場合
- 12カラムグリッドでBento UIを構成する
- 5.11 フォーム
- サブグリッドを使って親グリッドからまとめて配置をコントロールする
- コンテナクエリでレスポンシブにする
- 5.12 パンケーキ・スタック・レイアウト
- コンテンツの分量に応じてフッターの配置を変える
- フッターを常に画面下部に固定する
- ■ よくあるトラブル: iPhoneでツールバーが被って画面下部のフッターが見えなくなる
- ■ よくあるトラブル: コンテンツが画面からオーバーフローしてレイアウトが崩れる(CSSグリッドとフローレイアウトのautoの処理の違い)
- 5.13 フルブリード・レイアウト
- 1つのグリッドで2つの横幅をコントロールする
- <main>内の各セクションをコンテンツ幅にする
- セクションを全幅にして中身をコンテンツ幅にする
- 装飾を追加する
- 2段組みのレイアウトにする場合
- 5.14 聖杯レイアウト
- 聖杯レイアウトの構造をグリッドで構成する
- エリアにコンテンツを入れていく
- エリアの配置を変えてレスポンシブにする
- ■ よくあるトラブル: 中身に合わせた高さになって縦スクロールバーが表示されない
- 5.15 ダッシュボードUI
- ダッシュボードUIの構造をグリッドで構成する
- ヘッダーを入れる
- メインコンテンツを入れる
- サイドバーにメニューを入れる
- サイドバーをアニメーション付きで開閉させる
- ■ よくあるトラブル: 横幅を0にしてオーバーフローはoverflow-x: hiddenで隠しているのにパディングがオーバーフローして表示される
- モバイルではボタンをクリックしたらサイドバーを表示する
- ■ よくあるトラブル: frを使う場合(0frが0にならない)
- positionを使ってサイドバーを開閉する場合
- サイドバーを高さいっぱいに表示する場合
- 5.16 チャットUI
- チャットUIの構造をグリッドで構成する
- メッセージのレイアウトをグリッドでコントロールする
- ダッシュボードUIに入れて使用する場合
- Appendix
- デベロッパーツールでグリッドの構成を確認する
- グリッドと組み合わせて使用しているモダンCSS
- 5.1 構築するレイアウト