Flexboxとの違い
Flexbox は、横か縦の一方を選んでレイアウトできます。
CSS Grid レイアウトは、横と縦の両方でレイアウトでき、よりきめの細かい調整が可能です。
グリッドを作る
display: grid か display: inline-grid で CSS Grid レイアウトを開始できますが、これだけではグリッドが作れません。
grid-template(grid-template-rows / grid-template-columns)を設定して、グリッドを作ります。
横(columns)と縦(rows)を何分割するかを決めて、調整していきます。
よくありそうなサイトデザインを再現して、以下のように分けてみます。
html
<div class="grid-container"> <header class="header">header</header> <main class="main">main</main> <div class="menu">menu</div> <footer class="footer">footer</footer> </div>
css
a.grid-container { display: grid; grid-template-rows: auto 1fr auto; grid-template-columns: 100px 1fr; gap: 20px 15px; min-height: 100vh; } .header { order: 1; grid-column: 1 / 3; background-color: #ffff80; } .menu { order: 2; background-color: #ff8080; } .main { order: 3; background-color: #9f9fff; } .footer { order: 4; grid-column: 1 / 3; background-color: #9fff9f; }
便利な記述
見慣れない記述がいくつか見られます。確認してみましょう。
新しい単位 fr
CSS Grid レイアウトでは、fr という新しい単位が使えます。
fr は分割されたスペースのことで、1fr は利用可能なスペース1つ分ということになります。
auto と fr の違い
auto は中のコンテンツに合わせてサイズが変わります。
fr は空いたスペースを埋めてくれます。
組み合わせて使う必要があります。
Flexbox でも使える gap と order
gap と order は、Flexbox でも利用できますが、非常に便利です。
gap(grid-gap / row-gap / column-gap)
アイテムとアイテムの空きを設定できます。
これで最初や最後だけの margin を取り除く、という作業は必要なくなりました。
order
html を入れ替えることなく、レイアウトの表示順を入れ替えることができます。
また grid では、order でなくても下の grid-row と grid-column を設定して入れ替えることもできます。
grid-row / grid-column
grid の子属性のアイテムで、分割した範囲をどのように使うか指定できます。
grid のラインの始まりと終わりを指定するので、分割した数よりも1つ多い数値で設定します。
span 1 とすると、table のようにセル単位の指定もできます。
css
.header { grid-column: 1 / 3; } .menu { grid-row: 2 / 3; grid-column: 1 / 2; } .main { grid-row: 2 / 3; grid-column: 2 / 3; } .footer { grid-column: 1 / 3; }
決まった形であれば、名前付きが分かりやすい
特に決まりきったレイアウトであれば、grid-template-areas でレイアウトを視覚的に管理できます。
この時、grid-area には名前を設定します。
css
.grid-container { display: grid; grid-template-rows: auto 1fr auto; grid-template-columns: 100px 1fr; grid-template-areas: 'header header' 'menu main' 'footer footer'; gap: 20px 15px; min-height: 100vh; } .header { grid-area: header; background-color: #ffff80; } .menu { grid-area: menu; background-color: #ff8080; } .main { grid-area: main; background-color: #9f9fff; } .footer { grid-area: footer; background-color: #9fff9f; }
繰り返すタイルレイアウトも Flexbox より Grid が高機能
タイルレイアウトは、Flexboxでもできますが、CSS Grid レイアウトであれば、きめ細やかな調整が可能です。
html
<div class="card-container"> <div> 1 </div> <div> 2 </div> <div> 3 </div> <div> 4 </div> <div> 5 </div> <div> 6 </div> <div> 7 </div> </div>
css
.card-container { display: grid; grid-auto-rows: 360px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px 15px; } .card-container > div { display: flex; align-items: center; justify-content: center; border: 1px solid #000; }
grid-template の中で使える便利な記述
grid-template-columns と grid-template-rows で利用できる便利な記述があります。
repeat
繰り返しを簡単に記述できます。
例えば10回記述するとこうなります。
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
repeat を使うとすっきりします。
grid-template-columns: repeat(10, 1fr);
auto-fit / auto-fill
repeat の繰り返し数の代わりに利用できるキーワードで、親のスペースが余った部分の埋め方を設定できます。
auto-fill は、親のスペースが余った場合、空のグリッドで埋めます。
auto-fit は、親のスペースが余った場合、アイテムの幅で埋めます。
minmax
アイテムの最小値と最大値を設定できます。
レスポンシブのときに非常に役立ちます。
grid-auto で規定値を設定
今回のタイルレイアウトだと、アイテムの高さがレスポンシブに影響しないので、 grid-auto-rows で規定値を設定しておくと便利です。
重なりを使ったレイアウト
grid アイテムを重ねて、z-indexを変更して複雑なレイアウトができます。
サンプルが適当ですみません。
html
<div class="container"> <div> 1 </div> <div> 2 </div> <div> 3 </div> <div> 4 </div> <div> 5 </div> <div> 6 </div> <div> 7 </div> </div>
css
.container { display: grid; grid-template-rows: repeat(8, minmax(80px, 1fr)); grid-template-columns: repeat(6, minmax(120px, 1fr)); min-height: 100vh; } .container > div { display: flex; align-items: center; justify-content: center; background-color: #f1fca2; } .container > div:nth-child(1) { grid-row: 1 / 3; grid-column: 1 / 6; background-color: #eee; } .container > div:nth-child(2) { grid-row: 1 / 5; grid-column: 5 / 7; background-color: #80ffff; z-index: 10; } .container > div:nth-child(3) { grid-row: 3 / 7; grid-column: 1 / 2; } .container > div:nth-child(4) { grid-row: 2 / 8; grid-column: 2 / 3; background-color: #fb8383; z-index: 20; } .container > div:nth-child(5) { grid-row: 4 / 7; grid-column: 6 / 7; background-color: #e787f7; z-index: 30; } .container > div:nth-child(6) { grid-row: 3 / 7; grid-column: 3 / 6; } .container > div:nth-child(7) { grid-row: 7 / 9; grid-column: 1 / 7; background-color: #90ff80; }
まとめ
案件で使ってみて、便利だと思いました!
コメント