縦横のセルを定義し、左上から順番にアイテムを並べていく方式です。display: grid はこの要素がグリッドの親コンテナであることを示します。grid プロパティはグリッドコンテナ内のセルを定義します。下記の例では縦方向に 2rem 2rem の2行、横方向に 4rem 4rem 4rem の3列、6個のセルを定義しています。
.container-grid { display: grid; grid: 2rem 2rem / 4rem 4rem 4rem; }
<div class="container-grid"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> <div class="box">E</div> <div class="box">F</div> </div>
grid-auto-flow はアイテムをセルに並べていく方向を指定します。column を指定すると行が埋まると、列を増やしていきます。
.container-grid-with-flow { display: grid; grid: 2rem 2rem / 4rem 4rem 4rem; grid-auto-flow: column; }
grid でエリアに名前を付け、アイテムに配置先のエリア名を指定する方式です。下記の例では、上部にヘッダ(header)、下部にフッタ(footer)を配置、中央を メニュー(menu)、メイン(main)、サイドバー(side) の3エリアに分割し、子アイテムをエリア名でそれぞれの場所に配置しています。
.container-named-area { display: grid; grid: "header header header" "menu main side" "footer footer footer"; .header { grid-area: header; } .menu { grid-area: menu; } .main { grid-area: main; } .side { grid-area: side; } .footer { grid-area: footer; } }
<div class="container-named-area"> <div class="box header">Header</div> <div class="box menu">Menu</div> <div class="box main">Main</div> <div class="box side">Side</div> <div class="box footer">Footer</div> </div>
grid でエリア名を指定する際に、エリアの高さ、横幅を指定することができます。下記の例ではエリアの高さを 2rem, 4rem, 2rem、横幅を 4rem, 16rem, 4rem に指定しています。高さに auto を指定すると最小の高さ、横幅に auto を指定すると最大の横幅となります。
.container-named-area-with-length { display: grid; grid: "header header header" 2rem "menu main side" 4rem "footer footer footer" 2rem / 4rem 16rem 4rem; .header { grid-area: header; } .menu { grid-area: menu; } .main { grid-area: main; } .side { grid-area: side; } .footer { grid-area: footer; } }
<div class="container-named-area-with-length"> <div class="box header">Header</div> <div class="box menu">Menu</div> <div class="box main">Main</div> <div class="box side">Side</div> <div class="box footer">Footer</div> </div>
grid-template-areas, grid-template-rows, grid-template-columns はエリア名、高さ、横幅を個別に指定します。
.container-named-area-with-length-2 { display: grid; grid-template-areas: "header header header" "menu main side" "footer footer footer"; grid-template-rows: 2rem 4rem 2rem; grid-template-columns: 4rem 16rem 4rem; .header { grid-area: header; } .menu { grid-area: menu; } .main { grid-area: main; } .side { grid-area: side; } .footer { grid-area: footer; } }
<div class="container-named-area-with-length-2"> <div class="box header">Header</div> <div class="box menu">Menu</div> <div class="box main">Main</div> <div class="box side">Side</div> <div class="box footer">Footer</div> </div>
grid-auto-rows, grid-auto-columns はセルの高さや横幅が指定されない場合のデフォルトサイズを指定します。
.container-with-default-size { display: grid; grid-template-areas: "itemA itemB itemC" "itemD itemE itemF"; grid-auto-rows: 2rem; grid-auto-columns: 10rem; .itemA { grid-area: itemA; } .itemB { grid-area: itemB; } .itemC { grid-area: itemC; } .itemD { grid-area: itemD; } .itemE { grid-area: itemE; } .itemF { grid-area: itemF; } }
<div class="container-with-default-size"> <div class="box itemA">A</div> <div class="box itemB">B</div> <div class="box itemC">C</div> <div class="box itemD">D</div> <div class="box itemE">E</div> <div class="box itemF">F</div> </div>
アイテムの開始ラインと終了ライン番号を指定する方式です。セル番号ではなく、線の番号で指定します。grid-area には、縦方向の開始線 / 横方向の開始線 / 縦方向の終了線 / 横方向の終了線 を指定します。
.container-line-number { display: grid; grid: 2rem 2rem / 4rem 4rem 4rem 4rem; .itemA { grid-area: 1 / 1 / 3 / 2; } .itemB { grid-area: 1 / 2 / 2 / 4; } .itemC { grid-area: 2 / 2 / 3 / 3; } .itemD { grid-area: 2 / 3 / 3 / 4; } .itemE { grid-area: 1 / 4 / 3 / 5; } }
<div class="container-line-number"> <div class="box itemA">A</div> <div class="box itemB">B</div> <div class="box itemC">C</div> <div class="box itemD">D</div> <div class="box itemE">E</div> </div>
下記の様に [...] でラインに好みの名前を付けることができます。[head-top] はヘッダエリアの上部のライン、[head-bottom] はヘッダエリアの下部のラインを、[x1]~[x4] は左から1本目~4本目のラインの名前を意味します。
.container-named-line { display: grid; grid: [head-top] "head head head" 2rem [head-bottom] [body-top] "menu main side" 2rem [body-bottom] [foot-top] "foot foot foot" 2rem [foot-bottom] / [x1] 4rem [x2] 4rem [x3] 4rem [x4]; .head { grid-area: head-top / x1 / head-bottom / x4; } .menu { grid-area: body-top / x1 / body-bottom / x2; } .main { grid-area: body-top / x2 / body-bottom / x3; } .side { grid-area: body-top / x3 / body-bottom / x4; } .foot { grid-area: foot-top / x1 / foot-bottom / x4; } }
<div class="container-named-line"> <div class="box head">Header</div> <div class="box menu">Menu</div> <div class="box main">Main</div> <div class="box side">Side</div> <div class="box foot">Footer</div> </div>
gap により、アイテム間のギャップ(隙間)を指定することができます。下記の例では、縦方向に 1rem、横方向に 4rem のギャップを指定しています。
.container-gap { display: grid; grid: 2rem 2rem / 3rem 3rem 3rem; gap: 1rem 4rem; }
<div class="container-gap"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> <div class="box">E</div> <div class="box">F</div> </div>
高さまたは横幅に auto-flow をつけると、その後の数値を無限回繰り返すのと同じ動作になります。下記の例では、2rem 2rem / 2rem 4rem 2rem 4rem 2rem 4rem... を無限回繰り返します。auto-flow は高さか横幅かどちらか一方に指定できます。
.container-auto-flow { display: grid; grid: 2rem 2rem / auto-flow 2rem 4rem; }
span を指定すると N 個分のアイテムの高さ・横幅を指定することができます。
.container-span { display: grid; grid: auto-flow 2rem / 2rem 2rem 2rem 2rem 2rem 2rem; } .span-3 { grid-column: span 3; }
<div class="container-span"> <div class="box">A</div> <div class="box span-3">B</div> <div class="box">C</div> <div class="box">D</div> </div>
auto を横幅に指定すると最大長に、高さに指定すると最低長となります。
.container-auto { display: grid; grid: 3rem auto 3rem / 3rem auto 3rem; }
<div class="container-auto"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> <div class="box">E</div> <div class="box">F</div> <div class="box">G</div> <div class="box">H</div> <div class="box">I</div> </div>
グリッドの長さ指定ではフラクションサイズ(fr)という単位を用いることができます。fraction は「分数」を意味します。下記では横幅の長さを、最大横幅の 1/10, 2/10, 3/10, 4/10 で指定しています。
.container-fr { display: grid; grid: 2rem / 1fr 2fr 3fr 4fr; }
<div class="container-fr"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> </div>
minmax(min, max) は最小値と最大値を指定します。下記の例で Bアイテムは、最小でも 30rem、最大でも 40rem の横幅に制限されます。
.container-minmax { display: grid; grid: 2rem / 2rem minmax(30rem, 40rem) 2rem; }
<div class="container-minmax"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> </div>
max-content は子アイテムの中で一番大きなアイテムの長さを示します。アイテムの中身がテキストの場合、アイテムの長さはテキストを改行無しで表示した場合のテキストの長さとなります。下記の例では1列目の横幅を、一番長いテキストの横幅にそろえています。
.container-max-content { display: grid; grid-template-columns: max-content auto; }
<div class="container-max-content"> <div class="box">Short text</div> <div class="box">X</div> <div class="box">Very very long long text</div> <div class="box">Y</div> <div class="box">Middle length text</div> <div class="box">Y</div> </div>
min-content は、子アイテムをなるべく小さく表示します。アイテムの中身がテキストの場合は、一番長い単語の長さになります。
.container-min-content { display: grid; grid-template-columns: min-content auto; }
<div class="container-min-content"> <div class="box">Congratulations is a long word.</div> <div class="box">X</div> <div class="box">Short text.</div> <div class="box">Y</div> <div class="box">Short text.</div> <div class="box">Z</div> </div>
fit-content(length) は基本的には length の長さとなりますが、min-content 以上 man-content 以下の範囲に制限されます。下記の例で、コンテナの横幅を広げたり狭めたりしても、左側のアイテムの横幅は、max-content(テキストを改行しない場合の横幅)より長くなることはなく、min-content(テキストを最大限改行した場合の横幅)より短くなることはありません。min-content~max-content の間は 50% となります。
.container-fit-content { padding: .5rem; border: 1px solid gray; overflow: hidden; resize: horizontal; display: grid; grid: 3rem / fit-content(50%) auto; resize: both; }
<div class="container-fit-content"> <div class="box">Congratulations is a long word. </div> <div class="box">X</div> </div>
repeat(times, length) は length を times 回指定します。repeat(3, 10rem) は 10rem 10rem 10rem と同じ意味を持ちます。
.container-repeat { display: grid; grid: 2rem / 2rem repeat(3, 10rem) 2rem; padding: .5rem; }
<div class="container-repeat"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> <div class="box">E</div> </div>
times に auto-fill を指定すると length で指定した長さのアイテムをコンテナ一杯まで並べます。auto-fit は minmax(min, max) と組み合わせることで min 以上 max 以下のアイテムをコンテナの幅いっぱいに並べることができます。下記の例で枠の横幅を変更して振る舞いを確認してみてください。
.container-repeat-auto-fill { display: grid; grid-template-columns: repeat(auto-fill, 6rem); padding: .5rem; } .container-repeat-auto-fit { display: grid; grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr)); padding: .5rem; }
<div class="container-repeat-auto-fill"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> <div class="box">E</div> </div> <div class="container-repeat-auto-fit"> <div class="box">A</div> <div class="box">B</div> <div class="box">C</div> <div class="box">D</div> <div class="box">E</div> </div>
dense は「密集」という意味を持ちます。大きさの異なるアイテムを詰めていく際、通常であれば直前のアイテムの次の位置に詰めますが、dense を指定すると空きスペースがあればそこに埋めます。
.container-no-dense { display: grid; grid: 2rem 2rem 2rem 2rem / 2rem 2rem 2rem; } .container-dense { display: grid; grid: auto-flow 2rem 2rem 2rem 2rem / 2rem 2rem 2rem; grid-auto-flow: dense; } .big { grid-row: span 2; grid-column: span 2; }
<b>no dense</b> <div class="container-no-dense"> <div class="box grid-item">A</div> <div class="box grid-item big">B</div> <div class="box grid-item big">C</div> <div class="box grid-item">D</div> </div> <b>dense</b> <div class="container-dense"> <div class="box grid-item">A</div> <div class="box grid-item big">B</div> <div class="box grid-item big">C</div> <div class="box grid-item">D</div> </div>
2023年9月の Chrome 117 がリリースされ、主要モダンブラウザでサブグリッド(subgrid)がサポートされました。下記の例ではコンテナの中にアイテムとしてカード(card)を表示しています。さらに、カードをサブグリッドとして扱い、カード内のタイトルなどの子要素をサブアイテムとして扱っています。これにより、各カード間のタイトルの高さをそろえたりすることが可能となります。下記の例で 「subgrid指定」のチェックボックスを On/Off して、サブグリッド指定時と未指定時の振る舞いを確認してください。
.container-subgrid { display: grid; grid-template-columns: repeat(auto-fit, 10rem); gap: .5rem 2rem; padding: .5rem; } .card { display: grid; grid-template-rows: subgrid; border: 1px solid #999; grid-row: span 2; padding: .5rem; } .card-title { font-weight: bold; font-size: 120%; } .card-pict { height: 5rem; text-align: center; border: 1px solid #999; }
<div class="container-subgrid"> <div class="card"> <div class="card-title">Short Title</div> <div class="card-pict">Picture</div> </div> <div class="card"> <div class="card-title">Long Long Long Title</div> <div class="card-pict">Picture</div> </div> <div class="card"> <div class="card-title">Very Very Very Very Long Long Long Long Long Title</div> <div class="card-pict">Picture</div> </div> </div>
グリッドのレイアウトを指定するものに下記があります。詳細は 「フレックス・グリッドのレイアウト」を参照してください。
.container-layout { display: grid; grid: 2rem / auto-flow 10rem; margin-bottom: 1rem; border: 1px solid #ccc; background-color: #eee; } .cjc-left { justify-content: left; } .cjc-center { justify-content: center; } .cjc-right { justify-content: right; } .cjc-space-between { justify-content: space-between; } .cjc-space-around { justify-content: space-around; } .cjc-space-evenly { justify-content: space-evenly; }
<div class="container-layout cjc-xxxx"> <div class="box">xxxx</div> <div class="box">xxxx</div> <div class="box">xxxx</div> </div>
親コンテナに指定するプロパティには下記があります。
子アイテムに指定するプロパティには下記があります。
grid: <grid-template> | <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>? | [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns> grid-template: none | [ <grid-template-rows> / <grid-template-columns> ] | [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]? grid-template-areas: none | <string>+ grid-template-rows, grid-template-columns: none | <track-list> | <auto-track-list> | subgrid <line-name-list>? grid-auto-flow: [ row | column ] || dense grid-auto-rows, grid-auto-columns: <track-size>+ grid-aria: <grid-line> [ / <grid-line> ]{0,3} grid-row, grid-column: <grid-line> [ / <grid-line> ]? grid-row-start, grid-column-start, grid-row-end, grid-column-end: <grid-line> <track-list> = [ <line-names>? [ <track-size> | <track-repeat> ] ]+ <line-names>? <auto-track-list> = [ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <auto-repeat> [ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <explicit-track-list> = [ <line-names>? <track-size> ]+ <line-names>? <line-name-list> = [ <line-names> | <name-repeat> ]+ <track-size> = <track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( <length-percentage [0,∞]> ) <fixed-size> = <fixed-breadth> | minmax( <fixed-breadth> , <track-breadth> ) | minmax( <inflexible-breadth> , <fixed-breadth> ) <grid-line> = auto | <custom-ident> | [ [ <integer [-∞,-1]> | <integer [1,∞]> ] && <custom-ident>? ] | [ span && [ <integer [1,∞]> || <custom-ident> ] ] <track-breadth> = <length-percentage [0,∞]> | <flex [0,∞]> | min-content | max-content | auto <inflexible-breadth> = <length-percentage [0,∞]> | min-content | max-content | auto <fixed-breadth> = <length-percentage [0,∞]> <line-names> = '[' <custom-ident>* ']' <track-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <track-size> ]+ <line-names>? ) <auto-repeat> = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? ) <fixed-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <fixed-size> ]+ <line-names>? ) <name-repeat> = repeat( [ <integer [1,∞]> | auto-fill ], <line-names>+ )