CSSのsubgrid(サブグリッド)の使い方



HTMLとCSSで実装する通常のコンテンツの横並びでは、横並びにしてから子要素の配置を決めるFlexboxより、配置の領域を設定してから要素を合わせるCSS Gridが採用されることが多いでしょう。

Webサイトのデザインを構築していく中、横並びレイアウトの要素の中のコンテンツは、コンテンツ量によっては並び合う要素同士で高さが揃わないことがあります。
対象の要素の子要素をどのように横並びにするかを指定するものですので、単純な指定では親要素から見て孫要素までは調整できません。

高さを揃える調整はJavaScriptを使って実装する方法などもありますが、できればCSSのみで実装したいところです。
一応、CSSのみの方法としてFlexboxでも、marginプロパティで調整が可能です。



CSS Gridではsubgrid(サブグリッド)を使うことで、手軽に横並びレイアウトの要素の中の高さを揃えることができます。
気になるWebブラウザのサポート状況は、以下のURLにて確認できます。

Can I use(CSS Subgrid)
https://caniuse.com/css-subgrid


主要ブラウザはすべてサポートされていますので、問題なく利用することができます。

ここでは、CSSのsubgridの使い方についてサンプルを交えてご紹介します。

CSSのsubgridの使い方


カード型レイアウトを作成する例で見ていきます。
まずはHTML。以下サンプルコードになります。
サムネイル画像とタイトル、説明文とテキストリンクという、シンプルなHTML構造を構築します。

HTML

<div class="card-container">

  <div class="card">
    <img src="images/sample01.jpg" alt="サムネイル画像の説明">
    <h2>タイトルタイトルタイトルタイトルタイトル</h2>
    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
    <a href="">記事を見る</a>
  </div>

  <div class="card">
    <img src="images/sample02.jpg" alt="サムネイル画像の説明">
    <h2>タイトルタイトルタイトルタイトルタイトルタイトル</h2>
    <p>テキストテキストテキストテキストテキストテキストテキストテキスト</p>
    <a href="">記事を見る</a>
  </div>

  <div class="card">
    <img src="images/sample03.jpg" alt="サムネイル画像の説明">
    <h2>タイトルタイトルタイトルタイトル</h2>
    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
    <a href="">記事を見る</a>
  </div>

  <div class="card">
    <img src="images/sample01.jpg" alt="サムネイル画像の説明">
    <h2>タイトルタイトルタイトルタイトルタイトルタイトル</h2>
    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
    <a href="">記事を見る</a>
  </div>

  <div class="card">
    <img src="images/sample02.jpg" alt="サムネイル画像の説明">
    <h2>タイトルタイトルタイトルタイトル</h2>
    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
    <a href="">記事を見る</a>
  </div>

  <div class="card">
    <img src="images/sample03.jpg" alt="サムネイル画像の説明">
    <h2>タイトルタイトルタイトルタイトルタイトル</h2>
    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
    <a href="" class="txt-link">都築を見る</a>
  </div>

</div>


CSSクラス「card-container」のブロックに「card」のコンテンツブロックを6つ用意しました。

続いて、CSS Gridでカード型レイアウトを構築します。
以下、CSSのサンプルコードになります。

CSS

.card-container {
  padding: 1.25rem;
  background-color: #eef;
  max-width: 1280px;
  margin-inline: auto;

  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.25rem;
}

.card {
  background: #fff;
  border: 1px solid #ccc;
  border-radius: 10px;
  padding: 1rem;

  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  gap: 0.75rem;
}

.card img {
  width: 100%;
  max-width: 100%;
  height: 250px;
  object-fit: cover;
  vertical-align: bottom;
}

.card h2 {
  font-size: 18px;
}

.card p {
  font-size: 14px;
}

.card a {
  text-decoration: none;
  font-size: 14px;
}


グリッドレイアウトのポイントは、card-containerとcardの要素に適用しているスタイルになります。
今回のグリッドレイアウトとサブグリッドに関わる部分は、わかりやすいように1行空けて指定しています。
他はスタイルはちょっとした見た目の調整です。各要素の余白はグリッドレイアウトのgapプロパティで調整しています。

親要素のcard-containerでは、これまでのグリッドレイアウトの基本的な指定になります。
repeat()で繰り返しパターンを指定、引数にはauto-fitでサイズが可変に対応させ、そのサイズはminmax()で最小値と最大値とします。

CSS

.card-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.25rem;
}



続いて、cardの各子要素のスタイルを見てみます。
子要素も「display: grid;」でグリッドレイアウトとします。
grid-rowプロパティでは、グリッドスパンの設定をしています。spanのあと半角スペースを空けてカード内の行数を指定します。今回のサンプルではサムネイル画像とタイトル、説明文とテキストリンクで4行となります。

そして、grid-template-rowsプロパティをsubgridと指定することで、横並びの子要素の中の要素の高さを揃えることができます。
subgridでは、親要素上で定義されたトラックを利用することができるため、gapプロパティの余白なども継承されますが、子要素で定義し直すこともできます。

CSS

.card {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  gap: 0.75rem;
}



以下、実装結果になります。
サムネイル画像、タイトル、説明文、テキストリンクと各要素が、コンテンツの量に合わせて高さが揃っているのが確認できます。

CSSのsubgrid(サブグリッド)を使ったカードレイアウト



このように、子要素もグリッドレイアウトとしてsubgridを適応させるだけで、手軽に親要素から見て孫要素の高さを揃えることができます。

余談


サイズがバラバラな画像をサムネイル画像として使う場合は、img要素に対してobject-fitプロパティで画像をトリミングしてあげると、サイズをキレイに整えることができます。

object-fitプロパティの利用方法については、以下の記事でご紹介しています。


ぜひ参考にしてください。