# 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; } ``` ![](https://i.imgur.com/9On7ijE.png) ```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 ."; } ``` ![](https://i.imgur.com/8kjfjnP.png) ```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"; } ``` ![](https://i.imgur.com/LVbvYRU.png) 🙄 需要注意的是 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); } ``` ![](https://i.imgur.com/uRUQRvp.png) ```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); } ``` ![](https://i.imgur.com/Z3vC1Nd.png) ![](https://i.imgur.com/cjUayak.png) ## 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); } ``` ![](https://i.imgur.com/ETBkvCW.png) ## 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) } ``` ![](https://i.imgur.com/5VaOkfq.png) ```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; } ``` ![](https://i.imgur.com/ioxejm0.png) # 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; } ``` ![](https://i.imgur.com/LUUo44w.png) 上圖為一個圖片瀑布排版,左邊三張寬長圖帶有 `.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; 也可以這樣寫*/ } ``` ![](https://i.imgur.com/3ittkQv.png) 將 `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; } ``` ![](https://i.imgur.com/pk1PPNj.png) 將該是寬圖、長圖還有大圖的 class 加上 grid-column 或 grid-row 上它們 span,它們有了我們想要的形狀,可是版面變成有很多空格。這時候可以在父層新增 grid-auto-flow 屬性設為 dense (預設為 row)⬇️⬇️⬇️⬇️⬇️ ![](https://i.imgur.com/FX8QXFh.png) 這樣就會填滿空隙,原理是原本排在後面的小圖看到前面有空位就會往前塞,所以這個屬性可以跳脫當時編寫 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 的名字一樣可以簡寫成這樣 */ } ``` ![](https://i.imgur.com/pHmJlc5.png) ## 適用 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) */ ``` ![](https://i.imgur.com/S0YOpsl.png)