CSS Gridはレスポンシブ対応のよく使うレイアウトにも便利!効果的に使用するポイントのまとめ
Post on:2018年2月8日
CSS Gridは今までに出来なかったレイアウトを実装するだけでなく、既存レイアウトをより簡単に実装する能力も備えています。サポートブラウザも十分になり、そろそろ既存レイアウトの実装方法を見直すタイミングかもしれません。
CSS Gridを使用して、3カラムや画像ギャラリーやカード型など、レスポンシブ対応のレイアウトを実装するテクニックを紹介します。
Common Responsive Layouts with CSS Grid
by @samsunginternet
下記は元記事のデモをピックアップしたものです。
※作者様にライセンスを得て掲載しています。
- CSS Gridで実装するヒーローイメージを備えた、3カラムのレイアウト
- CSS Gridで実装する画像ギャラリーのレイアウト
- CSS Columnで実装するカード型レイアウト
- CSS Gridで実装するヘッダ・フッタ付きの3カラムのレイアウト
CSS Gridで実装するヒーローイメージを備えた、3カラムのレイアウト
まずは大きなヒーローイメージを備えた、3カラムのレイアウト。
レスポンシブ対応で、ヒーローイメージは常にブラウザいっぱいに表示されます。
このレイアウトでCSS Gridを使用する大きな利点は3カラム内のカードに配置された画像です。Gridで幅を制御しているため、画像は高さにあったアスペクト比を維持して表示されています。
HTML
header要素とmain要素の2つで構成されており、3カラム内のカード状のarticle要素は数をいくつでも増やせます。
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 |
<body> <header> <img class="logo" src="image.jpg" alt="heart" /> <h1 class="heading">Grid into the future</h1> </header> <main> <section class="leading"> <p class="leading-bigtext">Hello</p> <p class="leading-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vitae semper quam. Praesent lobortis tellus quis erat condimentum, a bibendum tortor volutpat.</p> </section> <section class="cards"> <article> <img class="article-img" src="thumbnail.jpg" alt=" " /> <h1 class="article-title"> Title of article </h1> </article> <article> <img class="article-img" src="thumbnail.jpg" alt=" " /> <h1 class="article-title"> Title of article </h1> </article> ... ... </section> </main> </body> |
CSS
CSS Gridは3カラムのカードのレイアウトに使用されており、repeat()関数の最初の値はトラックの数、2番目の値はトラックの幅を定義します。
ヒーローイメージは背景にして「background-size: cover;」でいっぱいに表示し、カードは「object-fit: cover;」で画像をトリミングして表示しています。
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 |
/* Flex styles -------------------------------------------------*/ header { display: flex; align-items: center; } @media (min-width: 700px) { .leading { display: flex; align-items: center; } } /* Grid styles -------------------------------------------------*/ .cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); grid-gap: 30px; } /* Generic styles ----------------------------------------------*/ body { font-family: 'Quicksand', sans-serif; } header { padding: 10px; font-size: 2em; color: white; background-color: #333; } .logo { height: 50px; margin-right: 20px; } .leading { height: 240px; margin-bottom: 30px; padding: 30px; color: white; background: url('https://cdn.glitch.com/a5121e34-96b3-4a70-8227-040c51e64fae%2Fcat.jpg?1509635989509') center #333 no-repeat; background-size: cover; color: white; text-shadow: 0px 0px 5px #000; } .leading-bigtext { margin-right: 60px; font-weight: bold; font-size: 24vw; } @media (min-width: 700px) { .leading-bigtext { font-size: 140px; } } .leading-text { max-width: 900px; font-size: 1.2em; line-height: 1.4em; } .cards { max-width: 960px; margin: 0 auto 30px; } article { position: relative; } .article-img { height: 200px; width: 100%; object-fit: cover; } .article-title { position: absolute; bottom: 0; width: 100%; padding: 10px; background-color: rgba(255, 255, 255, 0.2); } |
CSS Gridで実装する画像ギャラリーのレイアウト
Flexboxで配置する時は、水平か垂直のいずれか1つの方向だけですが、CSS Gridを使用すると水平と垂直の2つの方向を制御してレイアウトすることができます。水平と垂直にまたいだセルを使用して、サイズの異なる画像を配置したギャラリーを実装します。
HTML
画像はfigure要素でいくつでも配置でき、ここでは8個のfigure要素を使用します。
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 |
<body> <header> <a href="#" alt="our company" class="logo"> <img src="image.jpg" alt="Our Logo" class="logo-img"> <h1 class="logo-text">Our Company</h1> </a> </header> <main class="main"> <section class="info1"> <h2>The Title</h2> <p>Some Text goes here, some text goes here, some text goes here, some text goes here.</p> <a href="#" class="info-link">Learn more...</a> </section> <figure class="figure1"> <img class="figure-img" src="figure.jpg" alt="a kitten"> </figure> <figure class="figure2"> <img class="figure-img" src="figure.jpg" alt="a kitten"> </figure> ... ... <figure class="figure7"> <img class="figure-img" src="figure.jpg" alt="a kitten"> </figure> </main> <aside class="sidebar"></aside> <footer class="footer"></footer> </body> |
CSS
「grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;」で6分割した幅に画像を配置します。3カラムのテクニックと同様に、画像をセルぴったりにさせるには「object-fit: cover;」を指定します。
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 |
/* grid styles ------------------------------------ */ @media (min-width: 600px) { main { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; } .info1 { grid-column: span 2; grid-row: span 2; } .info2 { grid-column: span 2; } .figure1 { grid-column: span 3; grid-row: span 2; } .figure6 { grid-column: span 2; } .figure7 { grid-column: span 3; } } /* flex styles -------------------------------------- */ .logo { display: flex; align-items: center; text-decoration: none; } /* generic styles ----------------------------------- */ body { max-width: 1600px; margin: 0 auto; font-family: 'Raleway', sans-serif; } header { padding: 10px; } .logo-img { margin-right: 10px; height: 60px; transform: scaleX(-1); } .figure-img { display: block; width: 100%; height: 100%; object-fit: cover; } .info1, .info2 { padding: 40px; background-color: #333; color: white; } .info-link { text-decoration: none; color: #ff9900; } |
CSS Columnで実装するカード型レイアウト
ビューポートの幅に応じて、列を変更するカード型レイアウトです。これだけであれば、FloatやFlexboxでも可能ですが、幅・高さともにサイズが不明なカードをいっぱいに配置するには、CSS Columnが適しています。
HTML
各カードはsection要素で実装されており、その中の要素の量は異なっていても問題ありません。
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 |
<body> <header> <h1 class="title">Card Layout</h1> <div class="options"> <a href="#" class="options-link link-active">Home</a> <a href="#" class="options-link">About</a> <a href="#" class="options-link">Gallery</a> <a href="#" class="options-link">Blog</a> <a href="#" class="options-link">References</a> <a href="#" class="options-link">Contant</a> </div> </header> <main> <section> <h2>見出し</h2> <p>本文</p> <a href="#" class="info-link">リンク</a> </section> <section> <h2>見出し</h2> <p>本文</p> <a href="#" class="info-link">リンク</a> </section> ... ... </main> </body> |
CSS
最初にビューポートのサイズに合わせて、column-countでカラム数と溝を定義します。この指定で、列はコンテンツでいっぱいになります。カードが複数の列に分割されるの避けるために、カードのsection要素に「break-inside: avoid;」を指定します。
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/* Layout styles -----------------------------------*/ @media (min-width: 620px) { main { column-count: 2; column-gap: 20px; } section { break-inside: avoid; } } @media (min-width: 960px) { main { column-count: 3; } } /* styles */ :root { --blue: #34495e; --green: #e74c3c; --yellow: #C9C243; --orange: #FFA644; --red: #3498db; } body { background-color: var(--blue); font-family: 'Ubuntu', sans-serif; color: #34495e; } main { max-width: 1200px; margin: 0 auto; padding: 20px; } header { max-width: 1200px; margin: 0 auto; padding: 20px 20px 0; } .title { font-size: 2.6em; text-align: center; color: white; margin-bottom: 20px } .figure-img { display: block; width: 100%; object: fit; } h2 { font-size: 1.4em; padding: 10px; } p { margin-bottom: 1em; padding: 0 10px; } .info-link { text-decoration: none; color: var(--green); padding: 10px; display: block; } .options { display: flex; align-items: center; justify-content: space-around; padding: 10px; border-top: 3px solid var(--red); border-radius: 3px; background-color: white; } .options-link { text-decoration: none; font-size: 0.9em; color: var(--red); } section { border-top: 3px solid var(--red); border-radius: 3px; background-color: white; margin-bottom: 20px; overflow: hidden; } .section-img { display: block; padding: 10px; margin: 0 auto; } .bigtitle { padding: 0; } .bigtitle-title { color: white; background-color: var(--red); margin-bottom: 10px; } .bigbottom-link { background-color: var(--green); color: white; } .profile { width: 80%; border-radius: 50%; margin-bottom: 10px; } @media (min-width: 620px) { .options-link { font-size: 1.4em; } } |
CSS Gridで実装するヘッダ・フッタ付きの3カラムのレイアウト
ヘッダ、フッタ、メインコンテンツ、両側のサイドバーの4つで構成された3カラムのレイアウト、いわゆる「Holy Grail Layout(聖杯レイアウト)」は古くからあるレイアウトですが、これをCSSハック無しで実装するのは非常に困難でした。しかし、CSS Gridを使用すると、シンプルなHTMLと、クリーンなCSSで簡単に実装できます。
HTML
HTMLは下記のように非常にシンプルです。サイドバーはnavとasideで、別のブロック要素にしても大丈夫です。
1 2 3 4 5 6 7 8 9 10 |
<body class="container"> <header>ヘッダ</header> <nav>ナビゲーション</nav> <main> <h1>見出し</h1> <p>本文</p> </main> <aside>サイドバー</aside> <footer>フッタ</footer> </body> |
CSS
小さいビューポート用にFlexboxの「flex-direction: column;」で、各要素を垂直に配置しておきます。そして、大きいビューポート用にGridを使用して聖杯レイアウトを実装します。3x3のグリッドを定義し、ヘッダとフッタは上行・下行の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 55 56 57 58 |
body { font-family: arial; } .container { display: flex; flex-direction: column; min-height: 100vh; } @media (min-width: 768px) { .container { display: grid; grid-template-columns: 200px 1fr 200px; grid-template-rows: auto 1fr auto; } } header { grid-column: span 3; padding: 30px; text-align: center; font-size: 1.4em; background-color: #369; color: white; } main { flex: 1; padding: 20px; } nav { background-color: #f90; padding: 20px; } aside { padding: 20px; background-color: #936; } footer { grid-column: span 3; padding: 30px; text-align: center; font-size: 1.4em; background-color: #690; color: white; } h1 { margin-bottom: 1em; font-size: 1.3em; font-weight: bold; } |
sponsors