本セッションの登壇者
セッション動画
今日は「CSS Subgridが遂に全ブラウザ対応。新時代のグリッドデザインを学ぼう」というお話をしていきます。
鹿野壮と申します。XのIDは @tonkotsuboy_comです。可愛い猫を飼っていて今日は左上ぐらいに猫が映っています。よろしくお願いいたします。

今日は素材をデザイナーの松下絵梨さんという方に手伝っていただきました。

今日はCSS Subgridの話をしていくんですけれども、SubgridというのはCSS Gridの機能をパワーアップさせたものです。そもそもCSS Gridって何なのかを簡単におさらいしたいと思います。

レベル1のCSS Gridでは限界がある
CSS Gridというのは行と列を使ったレイアウトのことです。
この「行」という漢字の右上の部分が横に並んでいるから、この方向が行であると覚えてください。

そして列は、「列」という漢字の右部分が縦方向になっているから列です。これが行列です。

どういったことができるかというと、たとえばエリア名を指定して、要素を柔軟に配置することができます。この例では、3つのエリアに要素を分けてそれぞれメインビジュアルとロゴとタイトルを表示しているレイアウトになっています。

あとは行列を繰り返したり、隙間を作ったりできます。repeat
という値を使うと、たとえば3行3列で100ピクセルの行列を作れます。

gap:
で行列間に隙間を開けてくださいという指定ができます。

あとは行と列の数を自動で変更したり、要素を敷き詰めてくださいといったことができるのがCSS Gridです。

これまでブラウザで対応していたものは、CSS Grid Layout Level 1でした。従来の仕様だと難しいレイアウトがありました。

たとえば、こういったレイアウトでカードが6つ並んでいます。それぞれの行でタイトルや説明文、画像の高さが全部揃っています。一番上のところはタイトルが2行あるから、要素を2行のタイトルの一番高い高さに合わせています。一方で、2行目にあるカードはタイトルが最大でも1行しかないんですね。なので、1行を最大の高さとしたレイアウトになるようにしています。

さらにこのレイアウトはレスポンシブ対応をするので、カードが先ほどは横に3つ並んでいましたが、今度は横に2つしか並ばなくなります。そうすると今度は、タイトルの1行分が最大の高さになります。下では文字が間違っていますがタイトル2行分が最大の高さになるみたいなことをしなければなりません。

これを従来のCSS Grid Layout Level 1で実現することは不可能でした。それぞれの高さがずれてしまうんです。たとえば、左上端のタイトルの高さと、真ん中のタイトルの高さと、右上端の高さがずれてしまうんですね。これをCSSだけで実現することは不可能です。

行列が入れ子にできるように
ではどうやっていたかというと、私も開発の現場でよくやるんですけれども、JavaScriptを使って実現していました。まず行ごとの最大の高さを計算して、各行にその高さを適用して、ウィンドウサイズが変わるごとに、またはブレイクポイントをまたぐごとに高さを計算し直して、みたいなことをやっていたわけです。当然JavaScriptを使うので処理の負荷が高く、パフォーマンスの悪化につながります。こういったことをやってくれるライブラリ等も開発の現場ではよく使われているかなと思います。

これが今日の主題なんですけれども、これらを解決する行列の入れ子機能というのが全ブラウザで可能になりました。

どういうアプローチをするかというと、まず親の行列を作ります。今この状態だと8行3列の行列を作っています。

その中に子の行列を作ります。これは4行1列の行列を作っています。

作った親行列の中に子行列を配置します。こうやって実現することができます。

これらがsubgridという行列の入れ子が可能なCSS Grid Layout Level 2の仕様になります。

Subgridは2023年9月15日にChromeの117が、17日にEdge 117が対応して、全ブラウザに対応することになりました。

親の行のサイズに従って子のグリッド行のサイズが決まる
では実際のデモを見ていきましょう。エディターに行きます。今、HTMLはこのようになっています。メインの要素がカードコンテナに囲まれていて、各カード要素が含まれています。このカード要素はたくさん配置されていて、今最低限のレイアウトしか配置していないのでこういった形になっています。

では、これを先ほどの考え方に従ってレイアウトしていきましょう。今、下にCSSを出しました。まず親のコンテナに対してdisplay: grid:
を指定します。grid-template-columns
は今まであったCSS Grid Layout Level 1のものですけれども、ここに対してrepeat(auto-fit, minmax(300px, 1fr))
とします。これはどういう意味かというと、CSSグリッドのレイアウトをしてください、列のレイアウトは300ピクセル以上 1fr以下で適当なサイズで伸び縮みするようにしてくださいという意味です。

これを適用してリロードすると、こういうレイアウトになります。これが親のCSSグリッドです。300ピクセル以上 1fr以下で伸び縮みしながら、行列の数が親のウィンドウサイズに合わせて自動的に配置されて増減するようになっています。

ここから、カード要素、子供の要素に対してもdisplay: grid
を指定します。ここがポイントなんですけれども、この子要素の行のテンプレートサイズをgrid-template-rows
で指定します。さっきcolumns
で列のサイズを指定したので、今度はrows
を使って行のサイズを指定して、subgrid
と指定します。こうすると、この子グリッドのテンプレートの行が親のテンプレートの行に従うようになります。さらに、grid-row: span 4
と書きます。これは4行分のサイズを使ってくれという指定なんですけれども、こういった指定を組み合わせることで、親の行のサイズに従って子のグリッド行のサイズが決まるようになるので、必ず各タイトルの最大の高さに揃うようになります。上は2行分、下は1行分です。

さらに便利なのが、gap(ギャップ、隙間)を指定することができます。たとえば親グリッドにgap
を指定すればカード間の隙間を指定できます。ただ子のグリッド間のgapが大きすぎるので子は行間のgapを12ピクセルぐらいに小さくするなど、親子で別の行列のgapを指定できます。

ちなみに最近のブラウザの機能で、gridやsubgridをクリックすると、適用されているグリッドのレイアウトが見られるようになりました。これは全ブラウザで対応しています。

新しい知識を活用しよう
スライドに戻ります。後ほど公開するスライドに、先ほどの手順を簡潔に書いていますのでご覧ください。活用例として今回みたいな複雑なカードデザインにも使えますし、別の活用例もあります。これは画像のキャプションの高さを揃える例で、先ほどと似たようなアプローチです。親のCSS Gridを定義して、子をSubgridにして他の行の最大の高さに合わせているデモです。こちらからリンクに飛べます。

また、スライドのような12分割グリットシステムを昔bootstrapでやっていた方も多いと思うんですけれども、それをCSSのGridとSubgridで実現するデモもあります。こちらもぜひご覧ください。

まとめです。CSS Gridは行列を使ったレイアウトです。Subgridを使えば行列の入れ子ができます。これは2023年9月からChrome、Edge、Safari、Firefoxを含めて全ブラウザで対応しました。さまざまな行列レイアウトに適用できます。ぜひ新しい知識を取り入れて、楽しく楽にウェブ制作をしましょう!

Xでもフロントエンド技術を発信していますので、ぜひフォローいただければと思います。
ご清聴ありがとうございました。

TechFeed Experts Night#26で発表したサブグリッドについて話しましたが、動画・文字起こしが公開されました💐
Subgridの使い方を、ステップバイステップで解説しています📷