- CSS Subgrid は既存の Grid の限界を超え、親グリッド構造を下位の DOM 要素まで 拡張 できる機能
- 従来は 直接の子要素だけ がグリッドに参加できたが、subgrid を使えば
<ul>・<li> のような入れ子構造でも同じ グリッドセル配置 が可能
- コンテンツの長さの違いによって生じる 兄弟要素間の不均衡 を解消し、各カードやセクションが 動的に反応 するレイアウト構成を支援
- ただし 行の予約の問題、ライン番号のリセット、auto-fill ベースの流動的グリッドとの非互換性 など注意点もある
- 主要ブラウザでサポートされており、段階的な導入 が可能なため、今後の UI 設計の柔軟性 を大きく高める技術
Subgridの基本概念
- 初期の CSS Grid は 直接の子要素のみ がレイアウトに参加可能
- 例として、ポートフォリオ UI では
<ul> 内部の <li> 画像は基本的に 1 つのセルにまとめられる
grid-template-rows: subgrid, grid-template-columns: subgrid を使うと、親グリッドの 行・列定義を継承 する
- 各
<li> が親グリッドのセルに直接配置され、意味論的な HTML 構造と視覚的な整列 を同時に維持できる
- 同じ結果は Flexbox と入れ子の Grid でも実現できるが、subgrid は 単一のグリッド構造の共有 により、より簡潔なアプローチを提供する
新しいレイアウトの可能性
- ポートフォリオカードの例では、各
<article> が 2 列グリッド を持ち、画像とテキストを配置する
fr 単位は柔軟だが、各カードが独立して計算を行うため 列幅の不均衡 が発生する
grid-template-columns: subgrid を適用すると、親グリッドの列比率を すべてのカードが共有 する
- タイトルの長さなどコンテンツの変化に応じて グリッド全体が自動調整 される
- この方法により、兄弟要素間の 相互認識型レイアウト を実現できる
- 例: 「Infinite Supercomputer」というタイトルを短くすると、全カードの画像・テキスト比率が即座に調整される
Subgrid使用時の注意点(Gotchas)
行スペースの予約
- 列の共有は直感的だが、行を共有する場合は明示的な行予約 が必要
- 例: 料金表カードで各
<ul> の項目を同じ行に揃えるには、grid-row: span N で 行数を指定 する必要がある
- subgrid は基本的に 単一セルしか占有しない ため、複数行を使うにはまず 親グリッド領域の拡張 が必要
入れ子グリッドの番号
- subgrid は親の 行・列テンプレートは継承 するが、ライン番号はリセットされる
- 例: 親の 2〜5 番ラインを継承しても、内部では 1〜4 として再度番号付けされる
- 各グリッドは独自のインデックスを持つため、ライン番号は固有 ID ではなく相対インデックス として動作する
流動的グリッドとの非互換性
repeat(auto-fill, minmax()) 形式の fluid grid は subgrid と併用できない
- subgrid には 定義済みの列数 が必要で、
auto-fill・auto-fit はサポートされない
- 筆者はこの組み合わせの解決策を見つけられなかったと明記している
旧型ブラウザのサポート
- 2023 年以降、主要ブラウザでサポートされているが、対応率は 90% 未満
@supports not (grid-template-columns: subgrid) という条件文で 代替レイアウトを提供 できる
- 例: 画像とテキストを 縦積み に配置するフォールバック構造が提案されている
実例と結論
- Stripe 開発者サイト(stripe.dev) はページ全体を 1 つの大きなグリッドで構成し、複数の subgrid 階層 を通じて細かな配置を実現している
- subgrid は大規模レイアウトだけでなく 小規模な UI 調整にも有用
- プロジェクト全体を作り直す必要なく 段階的に導入 できる
- CSS レイアウトの 新しい柔軟性を確保する手段 として、実験的に活用する価値が高い
1件のコメント
Hacker Newsのコメント
Subgrid 機能は本当に素晴らしいが、最初のシンプルな例では
ul { display: contents }を使って子要素をグリッドレイアウトに参加させることもできるSubgrid 機能がどうしても必要でないなら、この方法のほうがより効率的
display: contentsは UL 要素をレイアウトから完全に取り除いてしまうそのため、スタイルを適用したり、その要素でUI イベントを受け取ったりできない
UL をハイライト領域やスクロール可能なセクションとして使いたいなら、subgrid のほうがはるかに有用
frの代わりに別の単位を使い、テキストにはfrを使って残りの空間を埋めさせればよい以前、価格比較 UI を作ったとき、subgrid がなくて本当に苦労した
2つのテーブルを横に並べて行を揃えるのは不可能だった
固定高さや JS の計算で解決することはできたが、React コンポーネント構造ではあまりにも非効率だった
Container queries のほうがより良い解決策ではないかと思った
ただ、グリッド全体の一貫性を保つには subgrid のほうが適しているかもしれない
参考までに CodePen の例 を見ると理解しやすい
しかも container を使うと新しいstacking contextが生まれて不便
subgrid と container を一緒に使えないのが残念。subgrid のサイズを子が参照できれば本当に強力だと思う
「結局
<table>レイアウトに戻ってきたのか?」という気がする<table>は問題解決のためのハックだったが、アクセシビリティや技術的制約が多かったGrid システムは視覚的配置のための道具であって、データ構造を表すテーブルとは異なる
今ではグリッドが標準として定着しているのだから、もうテーブルと比較しないでほしい
だが、レスポンシブ対応やアクセシビリティはまったく考慮されていなかった。結局、私たちはテーブルを再発明したようなものだ
<table>の問題は、コンテンツを説明する構造だったという点にある。グリッド自体には問題はない結局 CSS がその機能を改良された形で再実装したようなものだ
以前遭遇したgrid バグの1つは、
<img>要素のサイズをパーセント単位で指定すると、セルのサイズが元画像の大きさに引っ張られて歪む現象だったFirefox と Chromium の両方で発生し、関連バグは Mozilla Bug 1857365 にある
CSS がレイアウトのために文書構造情報の追加を必要とすることがしばしばあって残念
たとえば行数を明示しなければならない点がそう
あるいは、ある flex コンテナが別のコンテナの分布を模倣できるとよい
ただ、そうなると DX が複雑になる可能性が高い
なぜコード例では HTML と CSS の両方のファイルにスタイルが入っているのか気になった
最初の subgrid の例では CSS だけを見て、UL にどんなスタイルが適用されているのかしばらく探していた
「結局また grid に戻ってきたのか?」という感じがする
昔の HTML の時代にも似たようなことをしていた
Josh のブログ記事はいつも感嘆させられる
文章の明快さ、デザイン感覚、インタラクティブなウェブサイトまで、どれも素晴らしい
個人的には grid は今でも扱いづらい
文法もぎこちなく、レイアウトの感覚もなかなか合わない。Flexboxのほうがずっと直感的で柔軟だ
Flexbox はコンテンツ中心、Grid はコンテナ中心でサイズを制御する
コンテンツが複数の軸に自動で揃わず、すべてを手動で配置しなければならない
おそらく私が grid の本質をよく理解できていないか、自分の作業の種類と合っていないのだと思う