ウェブページの構成が思いのままに!display: grid を用いた柔軟な配置手法を基礎から学ぶ

はじめに: display: grid とは何か

ウェブページの見た目を整える際、要素をどのように配置するかは非常に重要な課題となります。これまで、要素の配置には様々な手法が用いられてきましたが、複雑な構成を実現しようとすると、記述が煩雑になったり、意図しない挙動に悩まされたりすることも少なくありませんでした。

display: grid は、そのような課題を解決するために登場した、CSSの強力な配置の仕組みです。これは、ページや要素の領域を行(水平方向)と列(垂直方向)からなる格子状の区画に分割し、それぞれの区画に要素を配置していく二次元の配置方式を提供します。

この方式を用いることで、HTMLの構造にとらわれすぎることなく、見た目上の配置を柔軟に制御することが可能となるのです。例えば、ページの主要な区画分け(ヘッダー、サイドバー、メインコンテンツ、フッターなど)や、多数の情報を整理して見せる一覧表示などを、以前よりもずっと少ない記述で、かつ直感的に実現できるようになります。

display: grid を理解し活用することで、ウェブ制作者はより洗練された、そして保守しやすいウェブページを構築するための大きな力を手に入れることができるでしょう。この記事では、その基本的な考え方から具体的な使い方まで、順を追ってご説明いたします。

グリッドレイアウトの基本的な仕組み

display: grid を用いた配置を理解する上で、いくつかの基本的な用語と概念を知っておく必要があります。これらを把握することで、実際の記述がスムーズに進むようになるでしょう。

  • グリッドコンテナー (Grid Container):
    display: grid; または display: inline-grid; が指定された親要素のことを指します。この要素が、内部の子要素を配置するための格子状の領域を作り出します。すべてのグリッドアイテムは、このコンテナーの境界内で配置されることになります。

  • グリッドアイテム (Grid Item):
    グリッドコンテナーの直接の子要素のことです。これらの要素が、コンテナーによって作られた格子の中のいずれかの区画に配置される対象となります。ただし、floatclearvertical-align といった一部のCSSプロパティはグリッドアイテムには効果がありません。

  • グリッド線 (Grid Line):
    グリッドコンテナー内の空間を分割する水平および垂直の線のことです。これらの線が格子を形成します。グリッド線には番号が振られており、通常は左から右へ、上から下へと1から始まる番号が自動的に割り当てられます。これらの線を利用して、アイテムの配置範囲を指定します。

  • グリッドセル (Grid Cell):
    隣り合う2本の水平グリッド線と2本の垂直グリッド線で囲まれた、グリッドの最小単位の区画を指します。ちょうど表計算ソフトの個別のマス目を想像すると分かりやすいかもしれません。

  • グリッドトラック (Grid Track):
    隣り合う2本の平行なグリッド線の間の空間のことです。水平方向のグリッドトラックは「行(row)」、垂直方向のグリッドトラックは「列(column)」と呼ばれます。

  • グリッドエリア (Grid Area):
    1つ以上のグリッドセルで構成される矩形の領域です。グリッドアイテムは、このグリッドエリアに配置されます。grid-template-areas という設定項目を使うと、このエリアに名前を付けて管理することも可能です。

  • fr 単位:
    display: grid 特有の単位で、「fraction(フラクション:部分、断片)」の略です。グリッドコンテナー内の利用可能な空間を、指定された比率で分配するために使用されます。例えば、1fr 2fr と指定すると、利用可能な空間を1:2の比率で分け合う2つの列(または行)が作られます。この単位のおかげで、柔軟で応答性の高い区画割が容易になります。

これらの基本的な仕組みを頭に入れておくことで、次の章で解説する具体的な設定項目の理解が深まるはずです。

親要素で使う主な設定項目(グリッドコンテナーの操作)

グリッドレイアウトを実現するためには、まず親要素(グリッドコンテナー)に対して、どのような格子を作るのか、そしてその格子にアイテムをどのように大まかに配置するのかを指定する必要があります。ここでは、グリッドコンテナーに適用する主要なCSSの設定項目を見ていきましょう。

  • display: grid または display: inline-grid

    • これが全ての始まりです。親要素に display: grid; を指定することで、その要素はブロックレベルのグリッドコンテナーとなります。
    • display: inline-grid; を指定すると、インラインレベルのグリッドコンテナーとなり、他のインライン要素と同様に振る舞います。
    • この宣言により、子要素はグリッドアイテムとして扱われるようになります。
  • grid-template-columnsgrid-template-rows

    • grid-template-columns: グリッドの列の幅や数を定義します。値には、固定値(例: 100px)、パーセント(例: 50%)、fr単位(例: 1fr 2fr)、キーワード(auto, min-content, max-content)などを指定できます。
    • grid-template-rows: グリッドの行の高さや数を定義します。指定できる値の種類は grid-template-columns と同様です。
      • 例: grid-template-rows: auto 1fr 100px; (1行目は内容に応じた高さ、2行目は残りの空間、3行目は100pxの高さ)
  • grid-template-areas

    • グリッドエリアに名前を付け、視覚的に分かりやすく配置を定義する方法です。文字列で格子の構造を表現します。
    • 各文字列は1つの行を表し、文字列内の各単語が1つのセル(または結合されたセル)に割り当てられる名前となります。同じ名前を隣接して記述すると、それらのセルが結合されて1つのエリアを形成します。
    • ピリオド (.) は空のセルを表します。
    • 例:
      grid-template-areas:
        "header header header"
        "sidebar main main"
        "footer footer footer";
      
    • この定義を使うと、子要素側で grid-area 設定項目にエリア名を指定するだけで簡単に配置できます。
  • gap (または row-gap, column-gap)

    • グリッド線間の隙間(溝、ガターとも呼ばれます)の大きさを指定します。
    • gap: 20px 10px; (行間の隙間が20px、列間の隙間が10px)
    • gap: 15px; (行間・列間ともに15px)
    • row-gap: 20px; (行間の隙間のみ指定)
    • column-gap: 10px; (列間の隙間のみ指定)
    • 以前は grid-gap, grid-row-gap, grid-column-gap という名前でしたが、現在は gap, row-gap, column-gap が標準的な名称です。
  • justify-itemsalign-items

    • グリッドアイテムのコンテナー内での行軸方向(横方向)および列軸方向(縦方向)の配置をまとめて指定します。
    • justify-items: 各グリッドアイテムを、それが配置されているグリッドエリアの行軸方向(横方向)にどのように配置するか。
      • 値: start, end, center, stretch (初期値)
    • align-items: 各グリッドアイテムを、それが配置されているグリッドエリアの列軸方向(縦方向)にどのように配置するか。
      • 値: start, end, center, stretch (初期値)
    • 例えば justify-items: center; とすると、全てのアイテムがそれぞれのセル内で水平中央に配置されます。
  • justify-contentalign-content

    • グリッド全体の、グリッドコンテナー内での配置を指定します。これは、グリッドのトラック(行や列)の合計サイズがコンテナーのサイズよりも小さい場合に効果を発揮します。
    • justify-content: グリッド全体の行軸方向(横方向)の配置。
      • 値: start, end, center, stretch, space-around, space-between, space-evenly
    • align-content: グリッド全体の列軸方向(縦方向)の配置。
      • 値: start, end, center, stretch, space-around, space-between, space-evenly
    • 例えば、3列のグリッドがコンテナ幅より狭い場合、justify-content: space-between; とすると、1列目は左端、3列目は右端、2列目はその中央に配置され、列間の空白が均等に分配されます。

これらの設定項目を組み合わせることで、多種多様な格子構造とその中での大まかなアイテム配置を定義することが可能となります。

子要素で使う主な設定項目(グリッドアイテムの操作)

親要素(グリッドコンテナー)で格子構造が定義されたら、次は子要素(グリッドアイテム)をその格子のどこに配置するかを指定していきます。子要素側で使う主な設定項目は以下の通りです。これらを用いることで、各アイテムがどのグリッド線からどのグリッド線までを占めるか、あるいはどの名前付きエリアに配置されるかを細かく制御できます。

  • grid-column-start, grid-column-end, grid-row-start, grid-row-end

    • これらの設定項目は、グリッドアイテムが開始するグリッド線と終了するグリッド線を指定します。
    • grid-column-start: アイテムが開始する垂直グリッド線の番号または名前。
    • grid-column-end: アイテムが終了する垂直グリッド線の番号または名前。この線の直前までがアイテムの範囲となります。
    • grid-row-start: アイテムが開始する水平グリッド線の番号または名前。
    • grid-row-end: アイテムが終了する水平グリッド線の番号または名前。この線の直前までがアイテムの範囲となります。
    • 例: grid-column-start: 2; grid-column-end: 4; (2番目の垂直グリッド線から始まり、4番目の垂直グリッド線の手前まで、つまり2列目と3列目を占める)
    • span キーワード: grid-column-end: span 2; (開始線から2つのトラックにまたがる)
    • 負の数も指定でき、これは末尾からのグリッド線を指します(例: -1 は最後のグリッド線)。
  • grid-columngrid-row

    • これらは上記4つの設定項目の短縮形です。
    • grid-column: <start-line> / <end-line>;
    • grid-row: <start-line> / <end-line>;
    • 例: grid-column: 2 / 4; ( grid-column-start: 2;grid-column-end: 4; と同じ意味)
    • grid-column: 2 / span 3; (2番目の線から始まり、3トラック分広がる)
    • スラッシュ(/)と終了線を省略すると、自動的に1トラック分の幅または高さになります (例: grid-column: 2;grid-column: 2 / span 1; とほぼ同等)。
  • grid-area

    • この設定項目は、アイテムを配置する最も柔軟な方法の一つです。2つの使い方があります。
      1. 親要素の grid-template-areas で定義されたエリア名を指定する。
        • 例: grid-area: header; (親で header と名付けられたエリアにアイテムを配置)
      2. grid-row-start / grid-column-start / grid-row-end / grid-column-end の値を一度に指定する短縮形として使う。
        • 例: grid-area: 1 / 2 / 3 / 4; (1行目2列目から始まり、3行目4列目の手前までを占めるエリア)
  • justify-selfalign-self

    • これらは、個々のグリッドアイテムが、自身に割り当てられたグリッドエリア内でどのように配置されるかを指定します。親要素の justify-itemsalign-items の設定を上書きします。
    • justify-self: グリッドアイテムの行軸方向(横方向)の配置。
      • 値: start, end, center, stretch (初期値は親の justify-items の値)
    • align-self: グリッドアイテムの列軸方向(縦方向)の配置。
      • 値: start, end, center, stretch (初期値は親の align-items の値)
    • 例: ある特定のアイテムだけをセル内で右寄せにしたい場合、そのアイテムに justify-self: end; を指定します。

これらの設定項目を駆使することで、アイテムを特定の場所に固定したり、複数のセルにまたがって配置したりと、非常に自由度の高い配置が実現できます。特に、HTMLの記述順序とは独立して視覚的な順序を制御できる点は、display: grid の大きな強みの一つと言えるでしょう。

display: grid を用いることの大きな利点

display: grid を学ぶことで、ウェブ制作者は多くの恩恵を受けることができます。従来の配置手法と比較して、以下のような大きな利点が挙げられます。これらを理解することで、どのような場面で display: grid が効果を発揮するのかが見えてくるでしょう。

  • 複雑な構成の容易な実現:

    • 二次元の格子構造を直接的に扱えるため、これまで複雑な入れ子や補助的な要素を必要としたページ全体の骨格(例えば、ヘッダー、フッター、サイドバー、メインコンテンツが絡み合うような構成)も、比較的少ないHTMLとCSSで直感的に構築することが可能です。
    • grid-template-areas を使用すれば、まるで設計図を描くように、視覚的に分かりやすい形で配置を定義できます。
  • 記述の簡潔化と可読性の向上:

    • float を使用した際の clearfix のようなお決まりの対処法や、position を多用することによる複雑な親子関係の管理から解放されます。
    • 結果として、CSSの記述量が減り、コード全体の見通しが良くなる傾向があります。これにより、他の人が書いたコードを理解したり、後から修正したりする際の負担が軽減されることも期待できます。
  • HTML構造と見た目の分離:

    • HTMLは文書の構造や意味を表現することに集中させ、見た目の配置はCSS (display: grid) に任せるという、関心の分離をより明確に実現しやすくなります。
    • これにより、HTMLのソースコード上の順序と、実際に画面に表示される順序を柔軟に変更できるため、例えばアクセシビリティを考慮したマークアップを行いつつ、視覚的には最適な配置を追求することが容易になるのです。
  • 保守性の向上:

    • 配置の変更がCSS側で完結しやすくなるため、デザインの修正や調整が必要になった際、HTML構造にまで手を入れる必要性が減ることがあります。
    • 特定の区画の幅や高さを変更したり、アイテムの表示順を入れ替えたりといった作業が、関連するグリッドの定義を修正するだけで済む場合が多く、保守作業の効率化に繋がります。
  • 応答性の高い設計との親和性:

    • fr単位や minmax() 関数、auto-fill / auto-fit キーワードなどを活用することで、画面の幅に応じて列数やアイテムのサイズが自動的に調整されるような、応答性の高い配置を容易に作ることができます。
    • メディアクエリと組み合わせることで、異なる画面サイズに対してグリッドの定義(例えば grid-template-columnsgrid-template-areas)を切り替えることにより、劇的に異なる配置パターンをスムーズに適用することも可能です。

これらの利点は、特に中規模から大規模なウェブサイトや、複雑な情報構造を持つウェブアプリケーションを開発する際に、その真価を発揮すると考えられます。

display: flex と display: grid の使い分けについて

display: grid が登場する以前から、要素の配置には display: flex(フレックスボックス)も広く活用されてきました。どちらも強力な配置の仕組みですが、それぞれ得意とする場面が異なります。これらを適切に使い分けることで、より効率的で堅牢なウェブページ構築が可能となります。

  • display: flex (フレックスボックス) の得意分野:

    • 一次元的な配置: フレックスボックスは、基本的に行方向または列方向のどちらか一方向に沿ったアイテムの配置や間隔調整を得意とします。
    • 具体的な用途例:
      • ナビゲーションメニューの項目を横一列に並べる。
      • フォームのラベルと入力欄を横並びにする。
      • カード内のテキストやボタンを上下中央揃えにする。
      • アイテム群を均等な間隔で配置する。
    • コンテンツの量に応じてアイテムが伸縮するような、柔軟な振る舞いをさせたい場合に特に有効です。主に部品単位や、コンポーネント内部の要素配置に適していると言えるでしょう。
  • display: grid (グリッドレイアウト) の得意分野:

    • 二次元的な配置: グリッドレイアウトは、行と列の両方を同時に考慮した、面での配置を得意とします。
    • 具体的な用途例:
      • ウェブページ全体の主要な領域(ヘッダー、サイドバー、メインコンテンツ、フッターなど)の骨格作り。
      • 商品一覧や写真ギャラリーのような、複数のアイテムを格子状に整然と並べる。
      • 複雑な区画分けや、アイテムが複数の行や列にまたがるような配置。
    • ページ全体の構造を定義したり、厳密な位置指定が求められる場面で力を発揮します。HTML構造に依存しすぎない、自由度の高い配置が可能です。
  • 使い分けの指針と併用:

    • 「ページ全体の大きな骨組みは display: grid で作り、その中の個々の部品(例えばヘッダー内のナビゲーションや、サイドバー内のメニューリストなど)の配置には display: flex を使う」というように、両者を組み合わせて使用するのが一般的で効果的なアプローチです。
    • コンテンツが主役で、その流れに沿って配置を決めたい場合は display: flex が、あらかじめ決められた区画にコンテンツをはめ込んでいくような場合は display: grid が向いている、と考えることもできます。
    • どちらか一方が絶対的に優れているというわけではなく、解決したい配置の課題に応じて、より適切な方を選択することが肝要です。時には、グリッドアイテム自身をフレックスコンテナーにすることもありますし、その逆も考えられます。

両者の特性をよく理解し、それぞれの長所を活かせる場面で使い分けることで、ウェブページの配置設計は格段に洗練され、管理しやすくなることでしょう。

グリッドレイアウトの簡単な活用例

display: grid の設定項目について学んできましたが、ここでは具体的なHTMLとCSSの記述例を通して、実際にどのように活用できるかを見ていきましょう。簡単な例をいくつかご紹介します。

例1: 基本的な3カラムレイアウト

ウェブページでよく見られる、ヘッダー、メインコンテンツ、サイドバー、フッターから成る構成を grid-template-areas を使って作ってみます。

<div class="container">
  <header class="header">ヘッダー</header>
  <nav class="sidebar">サイドバー</nav>
  <main class="main-content">メインコンテンツ</main>
  <footer class="footer">フッター</footer>
</div>
.container {
  display: grid;
  grid-template-columns: 1fr 3fr; /* サイドバーとメインの幅の比率 */
  grid-template-rows: auto 1fr auto; /* ヘッダー高さ自動、メイン可変、フッター高さ自動 */
  grid-template-areas:
    "header header"
    "sidebar main-content"
    "footer footer";
  gap: 10px; /* 各エリア間の隙間 */
  min-height: 100vh; /* ページ全体の高さを最低でも画面の高さに */
  text-align: center; /* 見た目のため */
}

.header {
  grid-area: header;
  background-color: #f0a0a0;
  padding: 20px;
}

.sidebar {
  grid-area: sidebar;
  background-color: #a0f0a0;
  padding: 20px;
}

.main-content {
  grid-area: main-content;
  background-color: #a0a0f0;
  padding: 20px;
}

.footer {
  grid-area: footer;
  background-color: #f0f0a0;
  padding: 20px;
}

この例では、grid-template-areas を使って各要素が配置されるべき名前付きエリアを指定しています。HTMLの記述順に関わらず、CSSで定義した通りの配置になることが確認できるでしょう。

例2: 応答性の高いカード型一覧

複数のアイテムをカードとして並べ、画面幅に応じて列数が自動的に変わるような一覧を作ってみましょう。repeat()auto-fit, minmax() を組み合わせるのがポイントです。

<div class="card-gallery">
  <div class="card">カード 1</div>
  <div class="card">カード 2</div>
  <div class="card">カード 3</div>
  <div class="card">カード 4</div>
  <div class="card">カード 5</div>
  <div class="card">カード 6</div>
</div>
.card-gallery {
  display: grid;
  /* 
    列の定義:
    auto-fit: コンテナーに収まる限り列を自動生成
    minmax(200px, 1fr): 各列の幅は最小200px、最大で利用可能な空間を均等に分け合う
  */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
  padding: 15px;
}

.card {
  background-color: #e0e0e0;
  padding: 20px;
  border: 1px solid #ccc;
  text-align: center;
  min-height: 100px; /* カードの最小高さ */
  display: flex; /* カード内部のテキストを中央揃えにするため */
  align-items: center;
  justify-content: center;
}

この設定により、コンテナーの幅が広ければ多くのカードが横に並び、狭くなれば自動的に列数が減ってカードが下に折り返されます。各カードの幅も柔軟に調整されるため、非常に応答性の高い一覧が簡単に実現できます。

これらの例は display: grid の可能性のほんの一部を示すものですが、その強力さと柔軟性の一端を感じ取っていただけたのではないでしょうか。

まとめ: display: grid で広がる配置の可能性

この記事では、display: grid の基本的な考え方から、親要素(グリッドコンテナー)と子要素(グリッドアイテム)で用いる主要な設定項目、そして display: flex との使い分け、具体的な活用例までを順にご紹介してまいりました。

display: grid は、ウェブページの要素配置に大きな自由度と効率性をもたらす仕組みです。 主なポイントを再度まとめますと、以下のようになります。

  • 行と列からなる二次元の格子構造で要素を配置する。
  • grid-template-columns, grid-template-rows, grid-template-areas などで格子を定義する。
  • grid-column, grid-row, grid-area などでアイテムの配置場所を指定する。
  • HTMLの構造と見た目の配置を分離しやすく、保守性が向上する。
  • fr単位や minmax()auto-fit など応答性の高い設計に役立つ機能が豊富である。
  • display: flex とは得意分野が異なり、ページ全体の骨格には grid、部品の配置には flex といった使い分けが効果的である。

display: grid を習得することは、現代のウェブ制作において非常に価値のある技術投資と言えるでしょう。初めは覚えるべき設定項目が多く感じるかもしれませんが、実際に手を動かしながら試していくうちに、その便利さと強力さを実感できるはずです。

複雑な配置も、以前よりずっと直感的かつ簡潔に記述できるようになることで、制作者はより創造的な部分に時間を割けるようになるかもしれません。ぜひ、ご自身のプロジェクトで display: grid を積極的に活用し、その可能性を探求してみてください。ウェブページの表現の幅が、きっと大きく広がることでしょう。

関連記事