みなさんは実案件でGridを導入していますか?
GridはIE以外の主要ブラウザでサポートされています。
そのため、IE対応をしなければならない案件ではなかなか導入ができないのが実情です。。。
しかし、マイクロソフトから正式に、「Internet Explorer 11 デスクトップアプリは 2022 年 6 月 15 日にサポート終了」とお知らせがありました!
そのため今後は、今まで使うことができなかったGridを含むモダンなCSSプロパティを使う機会が増えてくるのではないかと思います。
(※サポートが終了するからといってIE対応が終了するわけではないのですが…)
そこで今回は、Gridを使用した実践的なコーディングサンプルを3つご紹介しようと思います!
カード型レイアウト
まずはとてもコーディング頻度の高いカード型レイアウトです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <div class="card-grid"> <div class="card-grid__container"> <div class="card-grid__item c-card"> <div class="c-card__img-box"> <img class="c-card__img" src="https://picsum.photos/500/400/" alt=""> </div> <div class="c-card__text-box"> <h2 class="c-card__title">タイトル</h2> <p class="c-card__text">ダミーテキスト</p> <div class="c-card__button-box"> <a href="#" class="c-card__button">read more</a> </div> </div> </div> <div class="card-grid__item c-card"> <div class="c-card__img-box"> <img class="c-card__img" src="https://picsum.photos/500/400/" alt=""> </div> <div class="c-card__text-box"> <h2 class="c-card__title">タイトル</h2> <p class="c-card__text">ダミーテキスト</p> <div class="c-card__button-box"> <a href="#" class="c-card__button">read more</a> </div> </div> </div> <div class="card-grid__item c-card"> <div class="c-card__img-box"> <img class="c-card__img" src="https://picsum.photos/500/400/" alt=""> </div> <div class="c-card__text-box"> <h2 class="c-card__title">タイトル</h2> <p class="c-card__text">ダミーテキスト</p> <div class="c-card__button-box"> <a href="#" class="c-card__button">read more</a> </div> </div> </div> <div class="card-grid__item c-card"> <div class="c-card__img-box"> <img class="c-card__img" src="https://picsum.photos/500/400/" alt=""> </div> <div class="c-card__text-box"> <h2 class="c-card__title">タイトル</h2> <p class="c-card__text">ダミーテキスト</p> <div class="c-card__button-box"> <a href="#" class="c-card__button">read more</a> </div> </div> </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | .card-grid__container { display: grid; gap: 20px; max-width: 1210px; margin: 0 auto; box-sizing: content-box; @media (min-width: 641px) { grid-template-columns: repeat(auto-fit, minmax(390px,1fr)); padding: 40px; } @media (max-width: 640px) { padding: 20px; } } .c-card { filter: drop-shadow(4px 4px 20px rgba(0, 0, 0, 0.09)); .c-card__img { width: 100%; } .c-card__text-box { padding: 20px; background-color: #fff; } .c-card__title { font-size: 20px; font-weight: bold; } .c-card__text { font-size: 16px; } .c-card__button { font-size: 18px; font-weight: bold; } } |
ポイント解説
このコーディングのポイントは以下の部分です(重要な部分のみ抜粋)
1 2 3 4 5 6 7 8 9 | .card-grid__container { display: grid;//★1 gap: 20px;//★2 @media (min-width: 641px) { grid-template-columns: repeat(auto-fit, minmax(390px,1fr));//★3 } } |
Gridを使うと、子要素のレイアウトを親要素で制御できる点がポイントです。
親要素の.card-grid__containerに対して、★1を宣言し、子要素のレイアウトを★3で制御しています。
★2もポイントで、このように指定すると子要素間の余白が20pxになります。
marginと何が違うの?
と思ったかもしれません。
marginの場合、marginを打ち消すという作業が発生します。
例えば今回のサンプルの場合、nth-child:3n+1の要素に対してmargin-left:0 の記述が必要です。
しかし、gapを使うとその打ち消しが不要になります!
ちなみに、gapプロパティはFlexboxでも同様に使えます!(※もちろんIE以外)
・grid
・gap
・grid-template-columns
・minmax
Gallery(ギャラリー)型レイアウト
続いて、少し複雑なギャラリー型レイアウトです。
デモを見る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | <div class="gallery-grid"> <div class="gallery-grid__container l-gallery"> <div class="c-gallery-item" data-area="A" data-type="1"> <div class="c-gallery-item__img-box"> <img class="c-gallery__img" src="https://picsum.photos/200/300" alt=""> </div> <div class="c-gallery-item__text-box"> <h2 class="c-gallery__title">タイトル</h2> <p class="c-gallery__text">ダミーテキスト</p> <div class="c-gallery-item__button-box"> <a href="#" class="c-gallery__button">read more</a> </div> </div> </div> <div class="c-gallery-item" data-area="B" data-type="2"> <div class="c-gallery-item__img-box"> <img class="c-gallery__img" src="https://picsum.photos/200/300" alt=""> </div> <div class="c-gallery-item__text-box"> <h2 class="c-gallery__title">タイトル</h2> <p class="c-gallery__text">ダミーテキスト</p> <div class="c-gallery-item__button-box"> <a href="#" class="c-gallery__button">read more</a> </div> </div> </div> <div class="c-gallery-item" data-area="C" data-type="3"> <div class="c-gallery-item__img-box"> <img class="c-gallery__img" src="https://picsum.photos/200/300" alt=""> </div> <div class="c-gallery-item__text-box"> <h2 class="c-gallery__title">タイトル</h2> <p class="c-gallery__text">ダミーテキスト</p> <div class="c-gallery-item__button-box"> <a href="#" class="c-gallery__button">read more</a> </div> </div> </div> <div class="c-gallery-item" data-area="D" data-type="3"> <div class="c-gallery-item__img-box"> <img class="c-gallery__img" src="https://picsum.photos/200/300" alt=""> </div> <div class="c-gallery-item__text-box"> <h2 class="c-gallery__title">タイトル</h2> <p class="c-gallery__text">ダミーテキスト</p> <div class="c-gallery-item__button-box"> <a href="#" class="c-gallery__button">read more</a> </div> </div> </div> <div class="c-gallery-item" data-area="E" data-type="2"> <div class="c-gallery-item__img-box"> <img class="c-gallery__img" src="https://picsum.photos/200/300" alt=""> </div> <div class="c-gallery-item__text-box"> <h2 class="c-gallery__title">タイトル</h2> <p class="c-gallery__text">ダミーテキスト</p> <div class="c-gallery-item__button-box"> <a href="#" class="c-gallery__button">read more</a> </div> </div> </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | .gallery-grid__container { padding: 40px; padding: clamp(20px, calc(40 / 1440 * 100vw), 40px); @media (max-width: 640px) { padding: 20px; } } .l-gallery { max-width: 1038px; box-sizing: content-box; margin: 0 auto; display: grid; @media (min-width: 641px) { gap: clamp(10px, calc(20 / 1440 * 100vw), 20px); grid-template: "A B B C" 280px "A D E E" 280px / calc(395 / 1038 * 100%) calc(208 / 1038 * 100%) calc(167 / 1038 * 100%) calc(208 / 1038 * 100%); } @media (max-width: 640px) { gap: 20px; } } .c-gallery-item { filter: drop-shadow(4px 4px 20px rgba(0, 0, 0, 0.09)); display: flex; flex-direction: column; .c-gallery-item__img-box { width: 100%; position: relative; padding-top: 75%; } .c-gallery__img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } .c-gallery-item__text-box { padding: 10px; background-color: #fff; height: 100%; display: flex; flex-direction: column; } .c-gallery__title { font-size: clamp(16px, calc(20 / 1440 * 100vw), 20px); font-weight: bold; } .c-gallery__text { font-size: clamp(14px, calc(16 / 1440 * 100vw), 16px); } .c-gallery-item__button-box { margin-top: auto; text-align: right; } .c-gallery__button { font-size: clamp(14px, calc(15 / 1440 * 100vw), 15px); font-weight: bold; } } @media (min-width: 641px) { [data-area="A"] { grid-area: A; } [data-area="B"] { grid-area: B; } [data-area="C"] { grid-area: C; } [data-area="D"] { grid-area: D; } [data-area="E"] { grid-area: E; } [data-type="2"] { .c-gallery-item__img-box { padding-top: 45%; } } } |
ポイント解説
このサンプルのコーディングポイントは以下の部分です(重要な部分のみ抜粋)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | .l-gallery { display: grid;//★1 @media (min-width: 641px) { grid-template: "A B B C" 280px "A D E E" 280px / calc(395 / 1038 * 100%) calc(208 / 1038 * 100%) calc(167 / 1038 * 100%) calc(208 / 1038 * 100%); //★2 } } @media (min-width: 641px) { [data-area="A"] { grid-area: A;//★3 } [data-area="B"] { grid-area: B; } [data-area="C"] { grid-area: C; } [data-area="D"] { grid-area: D; } [data-area="E"] { grid-area: E; } } |
サンプル1つめと同様で、親要素のl-galleryに対して★1を宣言します。
次に、★2がポイントです。
★2のようにgrid-templateを使うと、子要素を配置するためのエリアを作ることができます。
以下のようなイメージですね!
最後に、★3以降の記述で、子要素をどこに配置するか指定します。
「grid-area:配置したいエリア」と書くことで、作成したエリアに配置することができます。
インナー幅からはみ出したレイアウト
最後は、インナー幅から要素がはみ出たデザインです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <div class="article-grid-layout"> <article class="p-article"> <div class="l-article-inner"> <h2>Grid Layoutを使うと色々便利</h2> <p>テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキスト </p> <p>テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキスト </p> <h2>Gridを使うとインナー幅を無視して画像をいっぱいに広げることができます</h2> <img class="p-article__wide-img" src="https://picsum.photos/500/400/" alt=""> <p>テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキスト </p> <h2>もちろんインナー幅に収めるように配置することも可能です</h2> <img src="https://picsum.photos/200/300/" alt=""> <p>テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキスト </p> </div> </article> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | .article-grid-layout { padding: 40px 0; } .l-article-inner { display: grid; grid-template-columns: minmax(20px, 1fr) minmax(auto, 800px) minmax(20px, 1fr); > * { grid-column: 2 / 3; + * { margin-top: 2em; } } } .p-article { .p-article__wide-img { grid-column: 1/4; width: 100%; height: 300px; justify-self: center; } h2 { font-size: 32px; font-weight: bold; } img { object-fit: cover; max-width: 100%; text-align: center; } } |
ポイント解説
このサンプルのコーディングポイントは以下の部分です(重要な部分のみ抜粋)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | .l-article-inner { display: grid;//★1 grid-template-columns: minmax(20px, 1fr) minmax(auto, 800px) minmax(20px, 1fr);//★2 > * { grid-column: 2 / 3;//★3 } } .p-article { .p-article__wide-img { grid-column: 1/4;//★4 } } |
まず、親要素に★1を宣言します
次に★2を宣言し、3カラムレイアウトを作成します。
次に、★3の記述をし、子要素全てを番号2~3のカラムに配置します
Gridを使うと、以下のように列と行に対して番号が振られるのでそれを利用しています
最後に、★4の記述をし、1~4のカラム全体に配置することで、インナー幅をはみ出したレイアウトの完成です!
子要素を親要素(インナー幅)からはみ出して画面いっぱいにするCSS
まとめ
以上、Gridを使った実践的なコーディングサンプルを3つご紹介しました。
一番最後のサンプル以外はFlexを使うと同じようにコーディングできますが、Flexを使うと記述量がさらに多くなってしまう点がデメリットです。
できればソースはシンプルに・見やすくしたいのでGridを使えるのであれば積極的に使うといいでしょう!
来る2022年6月以降に向けてGrid以外のモダンなCSSプロパティはキャッチアップしていきたいですね!
では!
▼参考記事
Webページでよく使用されるレイアウトに役立つCSS Gridの実装テクニックのまとめ
FlexboxとCSS Gridの使い分け方、よく見かけるUIコンポーネントをFlexboxとGridで実装するテクニックのまとめ