## Grid
[TOC]
----
### 簡介
```html
<style>
.container {
display: grid;
/* display: inline-grid; */
/* 設為網格布局以后,容器子元素(項目)的 float、display: inline-block、display: table-cell、vertical-align 和 column-* 等設置都將失效。 */
}
</style>
<div class="container">
<div class="item"></div>
<div class="item"></div>
...
</div>
```
網格布局,先將容器按網格劃分,再定義項目如何在網格上分布。
Flex 布局是軸線布局,只能指定"項目"針對軸線的位置,可以看作是一維布局。Grid 布局則是將容器劃分成"行"和"列",產生單元格,然后指定"項目所在"的單元格,可以看作是二維布局。Grid 布局遠比 Flex 布局強大。
本文檔主要內容是對 https://css-tricks.com/snippets/css/complete-guide-grid 、http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html 的精簡整理,方便快速查閱。
----
### 容器屬性
#### grid-template-columns、grid-template-rows
```css
.container {
grid-template-columns: ... ...;
/* e.g.
1fr 1fr
minmax(10px, 1fr) 3fr
repeat(5, 1fr)
50px auto 100px 1fr
*/
grid-template-rows: ... ...;
/* e.g.
min-content 1fr min-content
100px 1fr max-content
*/
}
```

```css
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
```

使用空格分隔的值列表定義網格的列和行。這些值代表軌道大小,它們之間的空間代表網格線(`[]` 中命名網格線)。
----
#### grid-template-areas
```css
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
```
一個區域由單個或多個單元格組成,`grid-template-areas` 屬性用于定義區域(area),對區域命名,方便項目引用。
一個區域命名不能既跨行又跨列,否則會被認為是無效值:
```css
.container {
grid-template-areas: 'a a c'
'a e f'
'g h i';
grid-template-areas: 'a b c'
'd d f'
'd h i';
}
```
----
#### grid-column-gap、grid-row-gap
```css
.container {
/* standard */
column-gap: <line-size>;
row-gap: <line-size>;
/* old */
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
```
```css
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
column-gap: 10px;
row-gap: 15px;
}
```

指定網格線的大小,即設置 列/行之間的間隔寬度。
注意,間隔僅在列/行之間創建,而不在外邊緣上。
----
#### justify-items
```css
.container {
justify-items: start | end | center | stretch;
}
```
定義項目在網格內的行軸方向上的對齊方式(左右對齊)。也可以通過 `justify-self` 屬性在單個項目上設置此行為。
```css
.container {
justify-items: start;
}
```

----
#### align-items
```css
.container {
align-items: start | end | center | stretch;
}
```
定義項目在網格內的列軸方向上的對齊方式(上下對齊)。也可以通過 `align-self` 屬性在單個項目上設置此行為。
```css
.container {
align-items: start;
}
```

----
#### justify-content
如果網格區域的總大小小于其網格容器的大小時,此屬性可以定義 所有網格 在 網格容器中的行軸方向上的對齊方式(左右對齊)。
```css
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
```
```css
.container {
justify-content: center;
}
```

----
#### align-content
類似 `justify-content` 屬性,此屬性可以定義 所有網格 在 網格容器中的列軸方向上的對齊方式(上下對齊)。
```css
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
```
```css
.container {
align-content: start;
}
```

----
#### grid-auto-columns、grid-auto-rows
```css
.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
```
指定任何自動生成的柵格軌跡(也稱為隱式柵格軌跡)的大小。當容器中的項目比單元格多時,或者當網格項放置在顯式網格之外時,將創建隱式軌跡。
為了說明如何創建隱式網格軌跡,請考慮以下內容:
```css
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px;
}
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
```

我們告訴`.item-b`從列第5行開始,到列第6行結束,但我們從未定義列第5行或第6行。因為我們引用了不存在的線,所以創建了寬度為0的隱式軌跡來填充間隙。(其實自動生成的軌道[不是0](https://jsbin.com/wutofafoyi/edit?html,css,output),并且每個軌道都是同等寬度,包括最后的項目所在軌道。)
我們可以使用 `grid-auto-columns` 和 `grid-auto-rows` 來指定這些隱式軌跡的寬度:
```css
.container {
grid-auto-columns: 60px;
}
```

(`item-b` 項目所在的軌道寬度也是 `60px`)
----
#### grid-auto-flow
```css
.container {
grid-auto-flow: row | column | row dense | column dense;
}
```
如果項目沒有顯式放置在網格上(默認情況),則自動放置算法會自動放置這些項目。此屬性控制自動放置算法的工作方式。
```css
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
```
觀察我們沒有放置的三個項目 b、c、d 是如何在可用行中流動的:

如果我們將 `grid-auto-flow`設置為 `column`,則 `item-b`,`item-c`,`item-d` 將沿著列向下流動:
```css
.container {
grid-auto-flow: column;
}
```

----
### 項目屬性
#### grid-column-start、grid-column-end、grid-row-start、grid-row-end
```css
.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto;
grid-column-end: <number> | <name> | span <number> | span <name> | auto;
grid-row-start: <number> | <name> | span <number> | span <name> | auto;
grid-row-end: <number> | <name> | span <number> | span <name> | auto;
}
```
通過引用網格線來確定項目在網格中的位置。
```css
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}
```

如果沒有聲明 `grid-column-end` / `grid-row-end`,則默認情況下該項目將跨越1個軌道。
項目可以相互重疊。您可以使用 `z-index` 來控制它們的堆疊順序。
這四個屬性的值還可以使用 `span` 關鍵字(不要用關鍵字做網格線名稱),表示"跨越",即左右邊框(上下邊框)之間跨越多少個網格。
```css
.item-1 {
grid-column-start: span 2;
/* 兩者效果一樣 */
/* grid-column-end: span 2; */
}
```
上面代碼表示,1號項目的左邊框距離右邊框跨越2個網格。
如果多個行共享相同的名稱,則可以通過它們的行名稱和計數來引用它們。
```css
.item {
grid-column-start: col-start 2;
}
```
----
#### grid-area
通過引用 `grid-template-areas` 定義的區域,指定項目放在哪一個區域。
該屬性也可以用作 `grid-row-start` 、 `grid-column-start` 、 `grid-row-end` 、`grid-column-end` 的簡寫。
```css
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
```
```css
.item-d {
grid-area: header;
}
/* or */
.item-d {
grid-area: 1 / col4-start / last-line / 6;
}
```

----
#### justify-self
定義項目在網格內的行軸方向的對齊方式(左右對齊)。用于覆蓋 `justify-items` 的配置。
```css
.item {
justify-self: start | end | center | stretch;
}
```
```css
.item-a {
justify-self: start;
}
```

----
#### align-self
定義項目在網格內的列軸方向的對齊方式(上下對齊)。用于覆蓋 `align-items` 的配置。
```css
.item {
align-self: start | end | center | stretch;
}
```
```css
.item-a {
align-self: start;
}
```

要對齊網格中的所有項目,也可以通過 `align-items` 屬性在網格容器上設置此行為。
----
### 屬性簡寫
#### grid-template
`grid-template-rows` 、 `grid-template-columns` 和 `grid-template-areas` 的簡寫。
```css
.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
/*等價于:*/
.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}
```
由于 `grid-template` 不會重置隱式網格屬性( `grid-auto-columns` 、 `grid-auto-rows` 和 `grid-auto-flow` ),這可能是您在大多數情況下想要做的,因此建議使用 `grid` 屬性而不是 `grid-template` 。
----
#### grid-gap
`row-gap` 和 `column-gap` 的縮寫。
```css
.container {
/* standard */
gap: <grid-row-gap> <grid-column-gap>;
/* old */
grid-gap: <grid-row-gap> <grid-column-gap>;
}
```
如果未指定 `row-gap` ,則將其設置為與 `column-gap` 相同的值。
----
#### place-items
`align-items` 和 `justify-items` 的簡寫。
```css
.center {
display: grid;
place-items: start center;
}
```
第一個值設置 `align-items` ,第二個值設置 `justify-items` 。如果省略第二個值,則將第一個值分配給兩個屬性。
----
#### place-self
`align-self` 和 `justify-self` 屬性的簡寫。
```css
.item-a {
place-self: center stretch;
}
```
第一個值設置 `align-self` ,第二個值設置 `justify-self` 。如果省略第二個值,則將第一個值分配給兩個屬性。
----
#### place-content
`align-content` 和 `justify-content` 的簡寫。
```css
.container {
place-content: start center;
}
```
第一個值設置 `align-content` ,第二個值設置 `justify-content` 。如果省略第二個值,則將第一個值分配給兩個屬性。
----
#### grid
`grid-template-rows` 、 `grid-template-columns` 、 `grid-template-areas` 、 `grid-auto-rows` 、 `grid-auto-columns` 和 `grid-auto-flow` 等屬性的簡寫。(注意:在單個網格聲明中只能指定顯式或隱式網格屬性)。
以下兩個代碼塊是等效的:
```css
.container {
grid: 100px 300px / auto-flow 200px;
}
.container {
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;
}
```
----
#### grid-column
`grid-column-start` 、 `grid-column-end` 的縮寫。
```css
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
}
```
如果沒有聲明結束線值,則默認情況下項目將跨越1個軌道。
----
#### grid-row
`grid-row-start` 、 `grid-row-end` 的縮寫。
```css
.item {
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
```
----
#### grid-area
`grid-row-start`、`grid-column-start`、`grid-row-end`、`grid-column-end`的簡寫。
```css
.item-d {
grid-area: 1 / col4-start / last-line / 6;
}
```
----
### 特殊單位和函數說明
#### repeat()
有時候,重復寫同樣的值非常麻煩,尤其網格很多時。這時,可以使用`repeat()`函數,簡化重復的值。上面的代碼用`repeat()`改寫如下:
```css
.container {
display: grid;
grid-template-columns: repeat(3, 33.33%);
grid-template-rows: repeat(3, 33.33%);
}
```
`repeat()`接受兩個參數,第一個參數是重復的次數(上例是3),第二個參數是所要重復的值。
`repeat()`重復某種模式也是可以的:
```css
.container {
grid-template-columns: repeat(2, 100px 20px 80px);
}
```
傳統的十二網格布局,寫起來也很容易:
```css
.container {
grid-template-columns: repeat(12, 1fr);
}
```
----
#### minmax()
`minmax()`函數產生一個長度范圍,表示長度就在這個范圍之中。它接受兩個參數,分別為最小值和最大值。
```css
.container {
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
}
```
上面代碼中,`minmax(100px, 1fr)`表示列寬不小于`100px`,不大于`1fr`。
----
#### fit-content()
函數使用可用的空間,但不會小于 `min-content`,也不會大于 `max-content`。
-----
#### fr 關鍵字
為了方便表示比例關系,網格布局提供了`fr`關鍵字(fraction 的縮寫,意為"片段")。如果兩列的寬度分別為`1fr`和`2fr`,就表示后者是前者的兩倍。
```css
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
```
[上面代碼](https://jsbin.com/hadexek/edit?html,css,output)表示兩個相同寬度的列。

`fr`可以與絕對長度的單位結合使用,這時會非常方便。
```css
.container {
display: grid;
grid-template-columns: 150px 1fr 2fr;
}
```
[上面代碼](https://jsbin.com/remowec/edit?html,css,output)表示,第一列的寬度為150像素,第二列的寬度是第三列的一半。

----
#### auto、min-content、max-content 關鍵字
**auto:**
`auto`關鍵字表示由瀏覽器自己決定長度。
```css
.container {
grid-template-columns: 100px auto 100px;
}
```
上面代碼中,第二列的寬度,基本上等于該列單元格的最大寬度,除非單元格內容設置了`min-width`,且這個值大于最大寬度。
**min-content:** 內容的最小大小。想象一行像“E pluribus unum”這樣的文本,最小內容可能是單詞“pluribus”的寬度。
**max-content:** 內容的最大大小。想象一下上面的句子,`max-content` 是整個句子的長度。
----
#### auto-fill 關鍵字
有時,單元格的大小是固定的,但是容器的大小不確定。如果希望每一行(或每一列)容納盡可能多的單元格,這時可以使用`auto-fill`關鍵字表示自動填充。
```css
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
```
[上面代碼](https://jsbin.com/himoku/edit?css,output)表示每列寬度`100px`,然后自動填充,直到容器不能放置更多的列。

除了`auto-fill`,還有一個關鍵字`auto-fit`,兩者的行為基本是相同的。只有當容器足夠寬,可以在一行容納所有單元格,并且單元格寬度不固定的時候,才會有[行為差異](https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit/):`auto-fill`會用空格子填滿剩余寬度,`auto-fit`則會盡量擴大單元格的寬度。
----
#### auto-fit 關鍵字
將所有列都放入空間中。更喜歡擴展列來填充空間,而不是空列。
這是 CSS Grid 中最著名的片段,也是有史以來最偉大的 CSS 技巧之一:
```css
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
```
`auto-fill` `auto-fit` 區別見: https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit/
----
#### Subgrid 子柵格
子網格是網格的一個非常有用的功能,它允許網格項擁有自己的網格,并從父網格繼承網格線。(目前只有 Firefox 支持這一功能)
```css
.parent-grid {
display: grid;
grid-template-columns: repeat(9, 1fr);
}
.grid-item {
grid-column: 2 / 7;
display: grid;
grid-template-columns: subgrid;
}
.child-of-grid-item {
/* gets to participate on parent grid! */
grid-column: 3 / 6;
}
```
- 開始
- 微信小程序
- 獲取用戶信息
- 記錄
- HTML
- HTML5
- 文檔根節點
- 你真的了解script標簽嗎?
- 文檔結構
- 已經落后的技術
- form表單
- html實體
- CSS
- css優先級 & 設計模式
- 如何編寫高效的 CSS 選擇符
- 筆記
- 小計
- flex布局
- 細節體驗
- Flex
- Grid
- tailwindcss
- JavaScript
- javascript物語
- js函數定義
- js中的數組對象
- js的json解析
- js中數組的操作
- js事件冒泡
- js中的判斷
- js語句聲明會提前
- cookie操作
- 關于javascript你要知道的
- 關于innerHTML的試驗
- js引擎與GUI引擎是互斥的
- 如何安全的修改對象
- 當渲染引擎遇上強迫癥
- 不要使用連相等
- 修改數組-對象
- 算法-函數
- 事件探析
- 事件循環
- js事件循環中的上下文和作用域的經典問題
- Promise
- 最佳實踐
- 頁面遮罩加載效果
- 網站靜態文件之思考
- 圖片加載問題
- 路由及轉場解決方案
- web app
- 寫一個頁面路由轉場的管理工具
- 談編程
- 技術/思想的斗爭
- 前端技術選型分析
- 我想放點html模板代碼
- 開發自適應網頁
- 后臺前端項目的開發
- 網站PC版和移動版的模板方案
- 前后端分離
- 淘寶前后端分離
- 前后端分離的思考與實踐(一)
- 前后端分離的思考與實踐(二)
- 前后端分離的思考與實踐(三)
- 前后端分離的思考與實踐(四)
- 前后端分離的思考與實踐(五)
- 前后端分離的思考與實踐(六)
- 動畫
- 開發小技巧
- Axios
- 屏幕適配
- 理論基礎
- 思考
- flexible.js原理
- 實驗
- rem的坑,為什么要設置成百分比,為什么又是62.5%
- 為什么以一個標準適配的,其它寬度也能同等適配
- 自適應、響應式、彈性布局、屏幕適配
- 適配:都用百分比?
- 番外篇
- 給你看看0.5px長什么樣?
- 用事實證明viewport scale縮放不會改變rem元素的大小
- 為什么PC端頁面縮放不會影響rem元素
- 究竟以哪個為設備獨立像素
- PC到移動端初試
- 深入理解px
- 響應式之柵格系統
- 深入理解px(二)
- 一篇搞定移動端適配
- flex版柵格布局
- 其他
- 瀏覽器加載初探
- 警惕你的開發工具
- JS模塊化
- webpack
- 打包原理
- 異步加載
- gulp
- 命名規范
- 接口開發
- sea.js學習
- require.js學習
- react學習
- react筆記
- vue學習
- vue3
- 工具、技巧
- 臨時筆記
- 怎么維護好開源項目
- 待辦
- 對前端MVV*C框架的思考
- jquery問題
- 臨時
- 好文
- 節流防抖