###### tags: `tutorials`
# Grid
## Grid Container (格線容器)
宣告 display: grid 或 display: inline-grid
來給一個元素建立格線容器(grid container)。
宣告以後,該元素的所有直接子元素會變成格線單位(grid item)
```
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
```
```
.wrapper {
display: grid;
}
```

## Grid Track (格線軌道)
宣告完 Grid Container 後要定義 Grid Track。
在格線裡透過 ***grid-template-columns*** 與 ***grid-template-rows*** 屬性定義了行與列。
```
.wrapper {
display: grid;
grid-template-columns: 200px 200px 200px;
}
```

## **fr** Unit(單位)
Grid Track 可以使用任何單位定義,
不過格線引入了額外的單位,以助於建立有彈性的格線軌道。
新的單位 fr 代表格線容器內,可用空間的分塊(fraction)。
* 以下的格線定義,會建立三個同等、且能依照可用空間縮放的長度軌道。
```
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
```

* 下例創建一個 2fr 的軌道,接著還有兩個 1fr 的軌道。
可用空間會因此被分為四塊:其中兩塊給第一個軌道、剩下兩塊給兩個軌道各一個。
```
.wrapper {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
}
```

* 下例把分塊與絕對大小做結合。
第一個軌道有 500px,這個固定的寬度,會因此從可用空間先割一塊出去。
接下來的空間會被劃分為三塊,並按比例指派給剩下的彈性軌道。
```
.wrapper {
display: grid;
grid-template-columns: 500px 1fr 2fr;
}
```

## Track listings with repeat() notation
* 含有許多軌道的格線能用 repeat(),以使軌道透過迴圈表列數次。例:
```
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
```
可以寫成:
```
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
```
* Repeat notation can be used for a part of the track listing. 下例中,建立了20px的軌道,接著重複1fr軌道六次,最後以20px的軌道做結。
```
.wrapper {
display: grid;
grid-template-columns: 20px repeat(6, 1fr) 20px;
}
```
* Repeat notation takes the track listing. 因此可以用它來建立重複的模式。下例的格線,會包含十個軌道:也就是1fr後面有2fr的軌道,並重複五次。
```
.wrapper {
display: grid;
grid-template-columns: repeat(5, 1fr 2fr);
}
```
## The explicit and implicit grid(明式與暗式格線)
在建立上例格線的時候,用 grid-template-columns 屬性指定了列軌道,但格線自己也建立了一行。
相較於使用 grid-template-columns 或 grid-template-rows 屬性的明式格線(explicit grid),這幾行就屬於暗式格線(implicit grid)。
你也能在暗式格線內透過 grid-auto-rows 與 grid-auto-columns 屬性,給軌道定義一套大小。
* 下例使用 grid-auto-rows 以確保由暗式格線建立的軌道,高度都會是 200 像素
```
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
```
```
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
}
```

## Track sizing and minmax(軌道縮放與 minmax())
在設定顯式格線或希望自動給軌道一個最小尺寸,
但也要確保它們擴展以適應任何添加的內容,
像是希望某行不能小於100px以避免跑版,
但如果內容高度超過300px,該行就要拉到那麼高。
針對這個情境,格線提供了 minmax() 函式。
* 下例中,針對 grid-auto-rows 指定了 minmax() 的數值。
它會指定高度最小要100px,最大則是auto。
auto意味著大小會檢查內容大小,並適配這一行cell內最高項目的高度。
```
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
}
```
```
<div class="wrapper">
<div>One</div>
<div>Two
<p>I have some more content in.</p>
<p>This makes me taller than 100 pixels.</p>
</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
```

## Grid Lines (格線)
It should be noted that when we define a grid we define the grid tracks, not the lines.
Grid then gives us numbered lines to use when positioning items.
In our three column, two row grid we have four column lines.

## Positioning items against lines
The following example demonstrates doing this in a simple way.
When placing an item, we target the line – rather than the track.
```
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
<div class="box5">Five</div>
</div>
```
```
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
.box2 {
grid-column-start: 1;
grid-row-start: 3;
grid-row-end: 5;
}
```
以下為縮寫 Line-positioning shorthands
```
.box1 {
grid-column: 1 / 4;
grid-row: 1 / 3;
}
.box2 {
grid-column: 1;
grid-row: 3 / 5;
}
```

## The *grid-area* property
You can use the grid-area property to specify where to place an item.
The syntax is <SPAN style="color:#F00">grid-row-start / grid-column-start / grid-row-end / grid-column-end</SPAN>.
Item1 will start on row 2 and column 1, and span 2 rows and 3 columns.
```
.grid-container {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 10px;
}
.item1 {
grid-area: 2 / 1 / span 2 / span 3;
}
```

## Gutters
Gutters or alleys between grid cells can be created using the column-gap and row-gap properties,
or the shorthand gap.
In the below example, I am creating a 10-pixel gap between columns and a 1em gap between rows.
```
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 10px;
row-gap: 1em;
}
```
* <SUB>Note: When grid first shipped in browsers the column-gap, row-gap and gap were prefixed with the grid- prefix as grid-column-gap, grid-row-gap and grid-gap respectively.</SUB>
* <SUB>Any space used by gaps will be accounted for before space is assigned to the flexible length fr tracks, and gaps act for sizing purposes like a regular grid track, however you cannot place anything into a gap. In terms of line-based positioning, the gap acts like a thick line.</SUB>

## Nesting grids
A grid item can become a grid container.
In this case the first item has some sub-items.
As these items are not direct children of the grid they do not participate in grid layout and so display in a normal document flow.

```
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
```
```
* {box-sizing: border-box;}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.box {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.box1 {
grid-column: 1 / 4;
}
.nested {
border: 2px solid #ffec99;
border-radius: 5px;
background-color: #fff9db;
padding: 1em;
}
```

### Subgrid
In the current specification, we would edit the above nested grid example to change the track definition of grid-template-columns: repeat(3, 1fr), to grid-template-columns: subgrid. The nested grid will then **use the parent grid tracks to layout items**.
```
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
display: grid;
grid-template-columns: subgrid;
}
```
## Layering items with z-index
Grid items can occupy the same cell,
and in this case we can use the z-index property to control the order in which overlapping items stack.
##### Overlapping without z-index
If we return to our example with items positioned by line number, we can change this to make two items overlap.
```
<div class="wrapper">
<div class="box box1">One</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
</div>
```
```
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
.box2 {
grid-column-start: 1;
grid-row-start: 2;
grid-row-end: 4;
}
```

#### use z-index
```
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
z-index: 2;
}
.box2 {
grid-column-start: 1;
grid-row-start: 2;
grid-row-end: 4;
z-index: 1;
}
```

## 參考資料
1. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout
2. https://www.w3schools.com/cssref/pr_grid-area.asp
3.