1. web design shake
  2. コーディング
  3. 入れ子レイアウトがもっと便利に!CSS Subgridの使い方
入れ子レイアウトがもっとn便利に!CSS Subgridの使い方

入れ子レイアウトがもっと便利に!CSS Subgridの使い方

当サイトは広告を使用しています。

CSS Subgrid(CSSサブグリッド)について

CSS Subgridとは、CSS Gridをさらに便利に扱えるようになるレイアウト機能です。これにより、今までは実装が難しかった入れ子のようなレイアウトも簡単に取り込むことができるようになりました。
サポート状況はモダンな主要ブラウザに対応しており(Can I use…)、これから徐々に使う人も増えていくと思います。

この記事ではSubgridについて優しく丁寧に解説していきますので、Subgridについて知りたい方必見です!

そもそもCSS Gridとは?という方へ

CSS Gridとは行と列によって構成されるグリッドシステムの中にアイテムを配置することができる機能です。
CSS Gridについては以下の記事にて丁寧に解説していますのでぜひ読んでみてください。

さて、冒頭話した通り、CSS GridがSubgridによってさらに便利になりました。
その便利な機能というのが親要素のCSS Gridを継承できるという機能になります。

継承できる?それはなにがすごいのにゃ?
平たく言えば、CSS Gridだけでは解決できなかった問題が簡単に解決できるようになったんだよ。

親要素のCSS Gridを継承できるといっても、何がすごいのかよくわからないですよね。
まずは以下の例を見てください。どんな問題が解決できるか分かると思います。

カードレイアウトの中身がそろわない問題

そう、カードの中身そろわない問題です!

よくあるケースになりますが、上の図のようにカードの中のコンテンツ量によって、カード内コンテンツの始まり位置が統一できない問題は直面したことがある人も多いのではないでしょうか。

従来はJSによって中身のコンテンツの高さを合わせるという、やや無理やりな手法で解決してきましたがこれにはブラウザの負荷がかかるという避けられない問題があり、デザイナーやコーダーをモヤモヤさせてきました。
SubgridではJSを必要とせずにコンテンツの中身の高さを合わせられるため、この問題が解決できます。

CSS Subgridではカードレイアウトの中身の開始位置を揃えることができる。

このように、Subgridを使うことでカードレイアウトの中身の始まり位置を揃えることができます。

それはすごいにゃ!
さっそく使ってみよう!後でプロパティについても解説するよ!

このようなイメージのカードレイアウトをSubgridを使って作成してみましょう。タイトルやテキストの長さはランダムに変えて、あえて開始位置に差が出るようにしてみます。

Subgridでカードレイアウトを作ってみる。


通常のCSS Gridだけであれば、カード内要素の開始位置はJSなどを使わない限りバラバラになるはずです。
Subgridであれば緑の破線のラインで、カード内の要素の行のラインを揃えることができます。

Subgridでカードレイアウトの中身の開始位置がそろうイメージ

1

HTMLを用意します。

以下のようなHTMLを用意します。
CSS Gridのコンテナしてcontainerというクラスがあり、その中にカード型の要素が入っています。カードの中には画像(サムネイル)と見出し、テキスト、ボタンがあります。
カード内のタイトル要素と、テキスト要素はランダムに長さを変えてみました。

<div class="container">
    <div class="card">
        <div class="img"></div>
        <h2>タイトル1タイトル1タイトル1タイトル1</h2>
        <p>吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル2タイトル2</h2>
        <p>何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル3タイトル3タイトル3</h2>
        <p>吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル4タイトル4</h2>
        <p>しかしその当時は何という考もなかったから別段恐しいとも思わなかった。この書生というのは時々我々を捕えて煮て食うという話である。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル5タイトル5タイトル5タイトル5</h2>
        <p>ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル6タイトル6</h2>
        <p>掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル7タイトル7タイトル7タイトル7</h2>
        <p>この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル8タイトル8タイトル8タイトル8タイトル8</h2>
        <p>その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル9タイトル9</h2>
        <p>のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
    <div class="card">
        <div class="img"></div>
        <h2>タイトル10タイトル10タイトル10タイトル10</h2>
        <p>どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。</p>
        <div class="button">
            記事を見る
        </div>
    </div>
</div>
2

CSSを指定します。

CSSはこのように指定しました。
カードにもCSS Gridを適用し、grid-template-rowssubgridを指定しました。
これによりカードにSubgridが適用されます。

.container {
    display: grid;
    grid-template-columns: repeat(5, 1fr); /* 5つのカラムを作成 */
    grid-template-rows: auto;
    gap: 50px; /* カード間の隙間 */
}

.card {
    display: grid;
    grid-template-rows: subgrid; /* ここでSubgridを使用 */
    grid-row: span 4; /* 4行分のスペースを占めるように調整 */
    gap: 20px; /* カード間の隙間も親要素を継承しているので上書き */
}

gapプロパティはコンテナ要素にもありますが、カードの方でも設定します。
今回はカード間の隙間を50px、カード内コンテンツの隙間を20pxで設定しました。

gapプロパティが親から継承されているのでカードの中身用に上書きする。

gapプロパティはそのままだとSubgridによって親のgapである50pxが継承されてしまいます。
カード内要素の間隔はもう少し小さい方が良いので、ここでは20pxで上書きしています。

3

完成!

これでCSS Subgridの設定は完了です!
カード内コンテンツの量によらず、それぞれのコンテンツの始まりの高さ位置がそろっていることが確認できると思います。さらに、カードの2行目(1~5枚目のカード)と、カードの2行目(6~10枚目のカード)を比べてみてください。それぞれの行ごとに、見出しの始まり位置が違うことが分かります。ウィンドウ幅を変えてみても破綻なく始まり位置が変化します。

完成形のコードをこちらに載せておきますね。(表示倍率を0.25倍にするか別タブで開いてみてください)
編集可能ですので、カード内コンテンツの量を変更してみてください。中身が変更されて高さが変わると、開始位置も変更されます。

See the Pen CSS Subgrid by web design shake (@webdesignshake) on CodePen.

さて、CSS Subgridに関連するプロパティを見ていきましょう。

grid-template-rows: subgrid;
grid-template-columns: subgrid;

CSS Gridの中でSubgridを利用する際に使われるプロパティです。
これらのプロパティは、ネストされたグリッド(子グリッド)が親グリッドの行や列のサイズを直接継承し、それに合わせて自身の行や列を調整するために使用されます。

grid-row: span 4;について解説

grid-row: span 4;
grid-column: span 4;

自身の行について指定した行(列)数分のグリッドスパンを設定します。
今回の場合、カード内コンテンツの要素数が、画像(サムネイル)と見出し、テキスト、ボタンと4つなので、span 4と指定します。これにより、4行(4列)分の高さ(幅)になります。
これはSubgridの機能ではなくCSS Gridの機能ですが今回のようにサイズが可変する場合に有効です。

いかがでしたか?
今までではJSでのフォローが必要だった複雑なレイアウトでも、Subgridを使えばCSSだけでより手軽に実装することができます。
レスポンシブや、内容量が可変するような要素にも柔軟に対応することができ、非常におすすめです。
ブラウザ対応状況も明るくなってきましたので、そろそろ取り入れてみるのも良いのではないでしょうか。

まとめ
  • Subgridを使うと入れ子レイアウトでの開始位置をそろえることができる
  • Subgridは親のCSS Gridを継承する
  • gapなど継承したプロパティは上書きして調整する

CATEGORY