# CSS Grid 筆記
此筆記是基於 freeCodeCamp.org 推出的 [CSS Grid Course](https://www.youtube.com/watch?v=t6CBKf8K_Ac&ab_channel=freeCodeCamp.org) 課程所撰寫。
# Your First Grid
⬇️ 以下屬性是下在父層 ⬇️
`grid-template-columns`:定義要有幾個欄位和他們的寬度。
`grid-template-rows`:定義要有幾列和他們高度。
`grid-template`:以上兩個屬性一起寫寫法(先 rows 再 columns)
`grid-column-gap` 與 `grid-row-gap`:個別設定垂直區塊與水平區塊的間距,
合併成 `grid-gap`,第一個值為 row 的間距,第二個值為 column 的間距。
# `fr` units & repeat
```css
/* example */
.wrapper {
display: grid;
grid-template-columns: repeat(12, 1fr); /* fr 平均分配單位(可以理解為 flex-grow: 1;) */
grid-template-rows: 40px 100px auto; /* auto 剩餘寬/高自動分配 */
}
```
```css
/* 速寫寫法 結果跟上面一樣*/
.wrapper {
display: grid;
/* 先 rows 再 columns */
grid-template: 40px 100px auto / repeat(12, 1fr);
}
```
# Positioning items
⬇️ 以下屬性是下在子層 ⬇️
`grid-column-start`:定義該 item 從哪條 column line 開始。
`grid-column-end`:定義該 item 從哪條 column line 結束。
`grid-column`:以上兩個屬性一起寫寫法。
`.grid-column-start&end` 的算法是基於 column lines,若有 2 欄就會有 3 個 column lines,3 欄就會有 4 個 column lines, etc.
```css
/* example */
.container {
display: grid;
grid-gap: 3px;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 40px 200px 40px;
}
.header {
grid-column-start: 1;
grid-column-end: 3;
/* grid-column:1 / 3; 速寫寫法 結果跟上面一樣*/
}
.footer {
grid-column: 1 / span 2;
}
```

```css
.footer {
grid-column: 1 / span 2;
}
意即 .footer 從 column line 1 開始
並 span 跨越 兩欄!或者當你不知道未來將
新增幾欄的時候你可以寫:
.footer {
grid-column: 1 / -1;
} /* 這會維持滿版,粉重要請記起來!*/
```
# Template Areas
`grid-template-areas`:用自己在子層 item 的標籤視覺化方式排版。
`grid-area`:用來替子層 item 命名。
```css
/* example */
.container {
height: 100%;
display: grid;
grid-gap: 3px;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
grid-template-areas:
"h h h h h h h h h h h h"
"m c c c c c c c c c c c"
"f f f f f f f f f f f f";
}
.header {
grid-area: h;
}
.menu {
grid-area: m;
}
.content {
grid-area: c;
}
.footer {
grid-area: f;
}
```
```css
/* 也可以在 grid-template-areas 使用點點 .
讓該格線空著 =======================>*/
.container {
// 略...
grid-template-areas:
". h h h h h h h h h h ."
"m c c c c c c c c c c c"
". f f f f f f f f f f .";
}
```

```css
/* 若要將 menu 往上延伸至 header
只需更改 grid-template-areas */
.container {
// 略...
grid-template-areas:
"m h h h h h h h h h h h"
"m c c c c c c c c c c c"
"f f f f f f f f f f f f";
}
```

🙄 需要注意的是 grid-template-areas 的格線排版都只能是矩形,不是矩形的話會破版喔!
# auto-fit & minmax
```css
/* example */
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(6, 100px);
grid-template-rows: repeat(2, 100px);
}
```

```css
/* 把 grid-template-columns 的單位改成 fr 格子
會 stretch (flex-grow = 1; 的概念) 但不會換行,如果寬度變很小,
就會六個擠在一起,如果寬度大就又會拉寬 */
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(2, 100px);
}
```


## auto-fit
```css
/* 當 columns 被設為 auto-fit 時,每當 .container 寬度增加 100px 就會一直增加欄位 */
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, 100px);
grid-template-rows: repeat(2, 100px);
}
```

## minmax
```css
/* 替 column 設定寬度最小值及最大值 */
/* 此範例情況下,若寬度為大於 100 的倍數又不足 100px 時會 strecth,當寬度又再可以超過 100 px
就會再新增一欄 */
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: repeat(2, 100px);
}
```
# implicit rows (grid-auto-rows)
```css
/* 承上題範例,columns 設定為
repeat(auto-fit, minmax(100px, 1fr))
後,當容器寬為 200px 時,會呈現兩欄,但從第
三列開始(即 item5)的高度就會變得跟內容本身
一樣高而已,因為一開始 grid-template-rows
也只有設定兩列而已,後面新增的列都是隱性建
立的 implicit rows,為了要符合
auto-fit & minmax 嘛!*/
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: repeat(2, 100px)
}
```

```css
/* 為了避免這個情況呢,可以新增 grid-auto-rows 屬性並設定寬度 */
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
/* grid-template-rows: repeat(2, 100px) */
grid-auto-rows: 100px;
}
```

# Awesome Image Grid
```css
/* example */
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-auto-rows: 75px;
}
.horizontal {
grid-column: 1 / span 2;
}
```

上圖為一個圖片瀑布排版,左邊三張寬長圖帶有 `.horizontal` class 比較適合寬版型,所以設定` grid-column: 1 / span 2;` 讓它們跨越 2 欄,但是因為 `grid-column-start` 設為 1 的關係,那三張圖會一直靠左導致右方版面會有空格。
```css
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-auto-rows: 75px;
}
.horizontal {
grid-column: auto / span 2;
/* grid-column: span 2; 也可以這樣寫*/
}
```

將 `grid-column-start` 設為 auto,那些寬長圖就不會一直黏在起始線了!
```css
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-auto-rows: 75px;
/* grid-auto-flow: dense; */
}
.horizontal {
grid-column: span 2;
}
.vertical {
grid-row: span 2;
}
.big {
grid-column: span 2;
grid-row: span 2;
}
```

將該是寬圖、長圖還有大圖的 class 加上 grid-column 或 grid-row 上它們 span,它們有了我們想要的形狀,可是版面變成有很多空格。這時候可以在父層新增 grid-auto-flow 屬性設為 dense (預設為 row)⬇️⬇️⬇️⬇️⬇️

這樣就會填滿空隙,原理是原本排在後面的小圖看到前面有空位就會往前塞,所以這個屬性可以跳脫當時編寫 HTML 標籤的順序~
# Bonus
## Name Lines
```css
.container {
height: 100%;
display: grid;
grid-gap: 3px;
grid-template-columns: 1fr 5fr;
grid-template-rows: 40px auto 40px;
}
.header {
grid-column: 1 / 3;
}
.menu {}
.content {
grid-column: 2 / 3;
}
.footer {
grid-column: 1 / 3;
}
```
```css
/* 我們可以在 grid-template-columns
替 grid lines 新增自定義名稱 */
.container {
height: 100%;
display: grid;
grid-gap: 3px;
grid-template-columns: [main-start] 1fr [content-start] 5fr [content-end main-end];
grid-template-rows:[main-start] 40px [content-start] auto [content-end] 40px [main-end];
}
.header {
grid-column: main-start / main-end;
/* grid-column: main; 若是 start&end 的名字一樣可以簡寫成這樣 */
}
.menu {}
.content {
grid-column: content-start / content-end;
/* grid-column: content; 若是 start&end 的名字一樣可以簡寫成這樣 */
/* grid-area: content; 這邊也可以寫成 grid-area 但要注意 column 跟 row 的名字都必須相同 */
}
.footer {
grid-column: main-start / main-end;
/* grid-column: content; 若是 start&end 的名字一樣可以簡寫成這樣 */
}
```

## 適用 justify-content、align-items.......
## Auto-fit VS auto-fill
```css
.container {
border: 1px solid black;
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: 100px 100px;
}
.container2 {
border: 1px solid black;
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-template-rows: 100px 100px;
}
/* 每當 container 寬度變寬 100px 時,auto-fit 會根據有幾個元素去增加欄位,此範例中只有四
個元素,超過 400px 的時候該四個元素會維持 max 的狀態 (1fr) 只會一直變寬;
然而 auto-fill 則會維持 minx 的狀態 (100px) */
```
