ウェブサイトのデザインにおいて、横に並べたカード内の要素の水平位置を揃えることは視認性を向上させる上で重要です。以前は、この水平位置を揃えるのには JavaScript を使用していました。しかし、2023 年に登場した CSS Grid の機能であるsubgridを使えば CSS を数行書くだけで簡単に出来てしまいます。

この記事では、subgrid を活用して、カード内の要素の水平位置を揃える方法を解説します。

まずは subgrid を使わずにカードを並べてみる

まずは、subgrid を使わずにカードを並べてみます。カードの HTML 構造は以下のようになっています。

<!-- カードを包括するコンテナ要素 -->
<div class="container">
  <!-- 並べるカードの基本構成 -->
  <div class="card">
    <div class="thumb"><img src="thumb.jpg"></div>
    <h2>タイトル</h2>
    <p>説明文</p>
    <a href="">詳細リンク</a>
  </div>
          ︙
  <div class="card">
    <div class="thumb"><img src="thumb.jpg"></div>
    <h2>タイトル</h2>
    <p>説明文</p>
    <a href="">詳細リンク</a>
  </div>
</div>

次に、CSS Grid でカードの並びを設定します。今回は、例としてカードを横に 3 つ並べたレイアウトで作成します。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.card {
  padding: 20px;
  background: #FFFFFF;
}

/* ここから先はカード内の要素の見た目に関するスタイル */

.card .thumb {
  margin: -20px -20px 0 -20px;
}

.card h2 {
  font-weight: bold;
  line-height: 1.4;
  text-align: center;
  font-size: 18px;
}

.card a {
  display: block;
  text-align: center;
  color: #FFFFFF;
  text-decoration: none;
  background: #6F86D6;
}

この、HTML 構造と CSS で実際にカードを並べたサンプルが以下になります。

See the Pen css-subgrid-card-alignment 01 by YUTSUZO (@YUTSUZO) on CodePen.

カード内の要素の水平位置がバラバラになってしまっています。調整を行うことで、ある程度は揃ってくれるようになりますが、完全に揃えようと思うと以前は JavaScript での実装が必要でした。

subgrid を使用してカード内の子要素の水平位置を揃える

そこで登場したのがsubgridです。subgridは、親要素のグリッドの情報を子要素に継承できる機能で、これにより、カード内の要素の水平位置を揃えることができます。

カードに subgrid を設定する

subgrid を使用して、カード内の要素の水平位置を揃えるために、カードに以下のようなスタイルを追加します。

.card {
  display: grid; /* カードにも grid を指定 */
  grid-template-rows: subgrid; /* grid-template-rows に subgrid を指定 */
  grid-row: span 4; /* カードが親要素のグリッドに対して何行分の要素であるかを指定 */
  padding: 20px;
  background: #FFFFFF;
}

この CSS を適用した結果が以下になります。

See the Pen css-subgrid-card-alignment 02 by YUTSUZO (@YUTSUZO) on CodePen.

カード内の要素の水平位置が綺麗に揃うようになりました。また、subgridを使用したことで、gapの値も親要素である.containerの値を引き継いでいます。

subgrid で親要素から継承されるもの

  • 列のサイズ :
    grid-template-columns: subgrid; を指定した場合。
  • 行のサイズ :
    grid-template-rows: subgrid; を指定した場合。
  • gap :
    親要素で指定したgapが適用される。

カードの子要素には grid-row の指定しておいたほうが良い

例えば、「画像・タイトル・詳細リンクは必ずあるけど、説明文は無いこともある」といった場合に、そのままでは以下のようになってしまいます。

See the Pen css-subgrid-card-alignment 03 by YUTSUZO (@YUTSUZO) on CodePen.

説明文がないカードだけ、詳細リンクの行が一つ上に移動してしまっています。こういったことが発生しないように、カード内の子要素(特に、無い可能性がある要素よりも後ろのもの)には何行目から何行目までを占める要素であるかを指定するgrid-rowを指定しておくといいでしょう。

.card a {
  grid-row: 4 / 5; /* 詳細リンクは4行目~5行目を占める要素 */
  text-align: center;
  color: #FFFFFF;
  text-decoration: none;
  background: #6F86D6;
}

こうすることで、説明文がない場合でも、詳細リンクが一番下の行に固定されます。

See the Pen css-subgrid-card-alignment 04 by YUTSUZO (@YUTSUZO) on CodePen.

終わりに

CSS の subgridを使うことで、横並びのカード内の要素の位置を簡単に揃えることができます。Flexbox や従来の Grid レイアウトでは難しかったこの調整も、subgrid を活用することでシンプルに実現可能です。ぜひ、試してみてください!

参考