願只有一個Grid Layout
相比較Multi-Columns Layout 和Flexible Box Layout,Grid Layuot更像是兩者的結合,當然這裡並不是說Grid Layout可以取代二者。
另外Grid Layout與當前非常火熱的Flexible Box Layout有一個本質上的區別就是維度不一樣。在使用Flexible Box Layout時,我們只能通過flex-direction定義主軸沿著某一方向,而在Grid Layout中截然不同。
二、核心用法
下面一步步去了解Grid Layout的核心用法:
1、巨集觀角度
巨集觀上可以將Grid Layout看成由行和列組成,這一點可以類比HTML中的table標籤,接下來用Grid語法宣告一個3行3列的結構。

.grid { display: grid; width: 300px; height: 300px; margin: 0 auto; grid: repeat(3, 1fr) / repeat(3, 1fr); } .grid > div:nth-child(odd) { background-color: #f5f5f5; } .grid > div:nth-child(even) { background-color: #eee; } 複製程式碼
通過設定display屬性為grid或者inline-grid,可以使得該元素變成Grid佈局容器,這基本是新增佈局宣告的一個通用套路。
上述grid屬性是一個複合屬性,等價下面的程式碼。
.grid { /* grid: grid-template-rows / grid-template-columns */ grid-template-rows: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr); } 複製程式碼
fr是Grid Layout中新增的單位,可以類比Flexible Box Layout中的flex-grow屬性。
上述九宮格中的每一個小格子在Grid中有一個專門的術語 -- Grid Cell。
2、微觀角度
從微觀的角度去看Grid Layout,首先你需要了解另一個術語 -- Grid Line。
不知道讀者們有沒有看過製作豆腐的過程,其中有一個步驟是用線將整塊的豆腐割開,那條線和上述的Grid Line是一樣一樣的。

那麼我們前面所說的行與列就需要用一個更專業的術語來描述 -- Grid Track。
Grid Track實際上就是相鄰的兩條Grid Line所形成的區域。
在Grid Layout中是看不見Grid Line的,但是可以使用它,它預設是數字編號的形式,還記得上面的九宮格佈局嗎?通過設定display和grid屬性,只是將容器劃分了結構,但是並沒有設定子元素的放置方式,幸好Grid Layout會為每一個子元素設定一個預設位置,例如第一行第一列的元素會這樣設定。
/* grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end */ grid-area: 1 / 1 / 2 / 2; 複製程式碼
上述的數字就是Grid Line的編號,並且它還支援自定義命名。
.grid { position: relative; margin: 100px auto; width: 500px; height: 500px; display: grid; grid: [line-row-1]1fr[line-row-2]1fr[line-row-3]1fr[line-row-4] / [line-col-1]1fr[line-col-2]1fr[line-col-3]1fr[line-col-4]; } .grid > div:nth-child(1) { grid-area: line-row-1 / line-col-1 / line-row-4 / line-col-3; } 複製程式碼

3、Grid Area
Grid Area也是一個比較重要的術語, 它主要由一個或者多個Grid Cell組成。前面的例子中,我們已經看到可以通過Grid Line為Grid Area分配空間,並且它還有另一種使用的方式。
.grid { position: relative; margin: 100px auto; width: 500px; height: 500px; display: grid; grid: "firstfirstsecond" "firstfirstfouth" "firstfirstthird"; } .grid > div:nth-child(1) { grid-area: first; } .grid > div:nth-child(2) { grid-area: second; } .grid > div:nth-child(3) { grid-area: third; } .grid > div:nth-child(4) { grid-area: fouth; } 複製程式碼
同樣是上述的例子,我們可以這樣放置子元素,是不是特別的友好。
4、絕對定位在Grid Layout中的表現
絕對定位大家應該很熟悉,其位置主要由包含塊或者初始化包含塊決定,通常我們都是通過設定父級元素的position屬性來確定包含塊,但是在Grid Layout中可以通過grid-area屬性達到同樣的效果。
.grid { position: relative; width: 400px; height: 400px; margin: 100px auto; display: grid; grid: repeat(2, 1fr) / repeat(2, 1fr); border: 1px dashed red; padding: 10px; } .demo1 { grid-area: 2 / 1 / 3 / 2; position: absolute; top: 30px; left: 30px; width: 100px; height: 100px; background: red; } 複製程式碼

5、其它
理解上面介紹的幾個術語和用法之後,基本上Grid Layout也沒有那麼神祕了。另外,例如Grid item之間的間隙以及它們的排列方式,基本上和Flexible Box Layout大同小異。
不過Grid Layout中還有很多好玩的知識點,例如margin凹陷的特性在Grid Layout中並不會發生。這些就留給讀者自己去探索吧。
三、最後
為什麼會起這個標題呢?主要是因為現在大部分的UI元件庫基本上都提供grid元件,就拿比較流行的Bootstrap元件庫來說,grid元件的實現:
- .row設定行,.col-*設定一個百分比寬度的列;
- .row通過負外邊距抵消容器的padding;
- .col通過左右內邊距實現元素之間的間隙效果;
- 通過媒體查詢設定斷點(breakpoints)實現響應式的佈局;
而CSS3新增的這個Grid Layout相比較這些實現方式,可以說是非常優秀了。相信不久我們可以告別Grid-Framework,只有一個CSS3的Grid Layout。