2022 年に IE のサポートが終了し、デジタル庁のサイトで12カラムグリッドが採用されていることが「デジタル庁のサイトやばすぎるwww」と話題になるなど、じわじわと CSS Grid の利用が広まっているのを感じます。
そんな中、Chrome 117 と Edge 117 が出たことで、待望のサブグリッド(subgrid)に主要ブラウザが対応済みとなりました。特に、サブグリッドは 12カラムグリッドで便利に使えそうですので、どんな感じで使えるのかを簡単にまとめてみました。
CSS Grid でグリッドを作成しても、そのグリッドで配置を制御できるのは子要素だけです。階層を維持したまま孫要素の配置を制御するためには、子要素でもグリッドを作成しなければなりません。
そのため、これまでは「CSS Gridの現状と12分割グリッド」で取り上げたように、子のグリッドを親と同じ構成で作るなど、いろいろと工夫が必要でした。
しかし、これからは子のグリッドを「サブグリッド」にすることで、親グリッドの構成(行・列の構成とギャップ)を自動的に継承できます。
たとえば、12カラムグリッドにリスト <ul> を配置し、リストの中身 A~D の <li> も同じ12カラムグリッドでコントロールしたい場合、次のように <ul> でサブグリッドを作ります。
<div class="grid">
<div class="text"> ... </div>
<ul class="subgrid">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
/* 12カラムグリッド */
.grid {
/* 12カラムグリッドを作成 */
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 30px;
}
/* サブグリッド */
.grid > ul.subgrid {
/* 12カラムグリッドの12列分に配置 */
grid-column: span 12;
/* サブグリッドを作成 */
display: grid;
grid-template-columns: subgrid;
}
/* サブグリッド内のアイテム */
.grid > ul.subgrid > * {
/* サブグリッドの3列分に配置 */
grid-column: span 3;
}
ここでは、<ul> の grid-template-columns を「subgrid」と指定しています。これにより、親の12カラムグリッドから列の構成と列のギャップ(間隔)を引き継いだサブグリッドが作成されます。<ul> は12カラムグリッドの 12 列分を使って配置していますので、サブグリッドも 12 列の構成になります。
これで、<ul> の中身 A~D の grid-column を「span 3」と指定すると、サブグリッドの3列分ずつを使用して配置され、4つ横並びの表示になります。
<ul> を 12カラムグリッドの 8 列分を使った配置にすると、サブグリッドも 8 列の構成になります。それに合わせて A~D の grid-column を「span 2」に変更し、サブグリッドの2列分ずつを使用した配置にすると次のようになります。
/* サブグリッド */
.grid > ul.subgrid {
/* 12カラムグリッドの8列分に配置 */
grid-column: span 8;
/* サブグリッドを作成 */
display: grid;
grid-template-columns: subgrid;
}
/* サブグリッド内のアイテム */
.grid > ul.subgrid > * {
/* サブグリッドの2列分に配置 */
grid-column: span 2;
}
親からサブグリッドに継承されたギャップサイズは上書きできます。次のように <ul> の gap を 0 にすると、サブグリッドのギャップがなくなります。
/* サブグリッド */
.grid > ul.subgrid {
/* 12カラムグリッドの8列分に配置 */
grid-column: span 8;
/* サブグリッドを作成 */
display: grid;
grid-template-columns: subgrid;
gap: 0;
}
ギャップを上書きした場合、サブグリッドに配置した外側の要素(A・D)と、内側の要素(B・C)とで、横幅のサイズが変わることに注意が必要です。これは、ギャップの扱いに起因します。ギャップをきちんと理解しておかないと、このあたりは違和感を感じるかもしれません。
ここまでのコードでサブグリッドにしたのは、<ul> の「列」だけです。「行」についてはサブグリッドにしていないため、親グリッドと関係なく構成が決まっています。
たとえば、A~D それぞれの配置に使う列数をサブグリッドの 2 列分から 4 列分に変更すると、2 行目が自動生成され、8 列×2 行の構成になります。
/* サブグリッド内のアイテム */
.grid > ul.subgrid > * {
/* サブグリッドの4列分に配置 */
grid-column: span 4;
}
これに対し、<ul> の grid-template-rows も「subgrid」と指定し、行・列の両方をサブグリッドにした場合、アイテム数に合わせて行列が自動生成されることはなくなります。その結果、次のような表示になります。
/* サブグリッド */
.grid > ul.subgrid {
…
/* サブグリッドを作成 */
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
gap: 0;
}
<ul> は 12 カラムグリッドの 8 列×1 行を使って配置していますので、サブグリッドの構成も 8 列 × 1 行になります。そして、行が自動生成されないため、配置に 4 列分を使用する A~D では C と D の配置先がなくなってしまいます。
このような場合、配置先がないアイテムはサブグリッドの最終行に配置される決まりとなっています。ここでは最終行=1 行目です。1 行目に A と B が配置されたあと、そこに重ねて C と D が配置されるため、上のように C と D だけを並べた表示になっています(Firefox と Safari では A の位置に C と D が重ねて配置され、D と B を並べた表示になります)。
Chrome のデベロッパーツール(DevTools)や Firefox の開発ツールを使うと、「ChromeでCSSグリッドの詳細な構造を確認する」のようにグリッドの構造を確認できます。
このとき、構成するグリッドに応じて、通常のグリッドであれば「grid」、サブグリッドであれば「subgrid」とバッジが表示されるようになっています。
ネストした要素の配置を、階層を維持したままコントロールできるようになるサブグリッド。12 カラムグリッドではもちろんのこと、いろいろな場面で活躍してくれそうです。