今天繼續來講 Grid 單元,昨天提到了對齊基本用法,今天繼續來講對齊與留白。不過一開始,還是先解釋清楚關於格線與單元之間的事情。
總覺得 15 天就會結束了說(笑)。
單元與格線
Grid 容器提供了格線系統,然後每個格線將內容區塊化(blockification)後,產生了 Grid 單元。這是整個 Grid Layout 的運作方式。那麼,對於 Grid 單元來說,格線系統就類似一種邊界,可以指定 Grid 單元在哪些軌道上。
基本的樣式為,
樣式 | 可用值 | 預設值 |
---|---|---|
grid-row-start , grid-row-end |
<軌道格線> |
auto |
grid-column-start , grid-column-end |
<軌道格線> |
auto |
grid-row |
<grid-row-start> / <grid-row-end>? |
auto |
grid-column |
<grid-column-start> / <grid-column-end>? |
auto |
grid-area |
軌道區域名稱或 <grid-row> / <grid-column>? 集合,定義順序為 row-start column-start row-end column-end |
auto |
指定軌道區域名稱
首先,軌道區域名稱比較容易理解,他是對應於 Grid 容器的 grid-template-areas
所指定的名稱,例如,
.grid-container {
display: grid;
grid-template-areas:
"nav nav nav"
"sidebar main main"
"sidebar main main"
"footer footer footer"
}
那麼當你想要把你的 Grid 單元放到指定區域名稱的時候,使用 grid-area
就會比較方便,
.grid-nav {
grid-area: nav;
}
.grid-sidebar {
grid-area: sidebar;
}
.grid-main {
grid-area: main;
}
.grid-footer {
grid-area: footer;
}
不知道大家還記得在開始的時候提到的網格單元容器嗎?
當你使用 grid-template-areas
定義區塊,然後接著使用 grid-area
來指定自訂區域名稱的時候,基本上就等同於 指定一個軌道區域 給這個 Grid 單元使用,所以,基本上他可以被翻譯成網格軌道格線的定義。
我們拿剛剛的例子來看,
.grid-nav {
grid-area: nav;
}
/* 等同於 */
.grid-nav {
grid-area: 1 1 2 4;
}
/* 等同於 */
.grid-nav {
grid-row: 1 / 2;
grid-column: 1 / 4;
}
/* 等同於 */
.grid-nav {
grid-row: nav-start / nav-end;
grid-column: nav-start / nav-end;
}
/* 等同於 */
.grid-nav {
grid-row-start: 1;
grid-row-end: 2;
grid-column-start: 1;
grid-column-end: 4;
}
/* 等同於 */
.grid-nav {
grid-row-start: nav-start;
grid-row-end: nav-end;
grid-column-start: nav-start;
grid-column-end: nav-end;
}
所以說,這邊的定義就會是一個所謂的網格單元容器(Grid item container block),根據一開始提到的定位點問題,使用 grid-area
的時候,請留意你的 Grid 單元在使用 position: absolute
的情況。之前已經說過了,這邊就不再多做贅述。
我們回到 grid-area
這件事情上面。當我們使用了命名單元的時候,如同之前所提到的,會提供 4 條隱性格線。所以當你使用 nav-start
與 nav-end
的時候也是會發生作用的。
接著,這個網格單元容器跟軌道一樣,是一種邊界的概念,換句話說,他一樣沒有能力去侷限 Grid 單元本身的定義或內容是否不能超出邊界(軌道)。另外,當你的單元軌道使用的軌道名稱,不存在於 Grid 容器定義裡的話,會出現奇怪的問題。
那個奇怪的問題我上次也提過了,這邊就不贅述了。
指定 <軌道格線>
我們之前有聊到軌道跟格線,還有隱性格線的介紹,現在我們就把他用在 Grid 單元上面。軌道格線的定義方式有幾種,
可用值 | 說明 |
---|---|
auto |
不解釋。 |
<自訂軌道名稱> |
請避開 -start , -end ,其餘不解釋。 |
<數字> |
將你所指定的 <數字> 的軌道,可以是負數。 |
<數字> <自訂軌道名稱> |
當 <自訂軌道名稱> 的軌道有複數數量時,該數字僅會計算相同名稱的軌道,如果數字是負數的話,計算方向就是反向,該數字不可為零 0 。 |
span [<數字>, <自訂軌道名稱>] |
跨度(維度)的軌道,如果是 <數字> 則表示要 跨過多少軌道數量,如果是 <自訂軌道名稱> 則表示直接跨到該<自訂軌道名稱> 的軌道。該數字 不可為負數或 0 。 |
Grid 格線軌道這件事情之前已經有提過了,這邊就不再繼續解釋說過的東西。我們直接舉一些例子來看看使用方法,
.grid-container {
display: grid;
grid-template-columns: [foo] 1fr [boo] 1fr [qoo] 1fr [ooo];
grid-template-rows: repeat(3, 1fr);
grid-auto-rows: 100px;
}
首先,基本的 Grid 單元軌道格線設定會是這樣,
.grid-item {
grid-column-start: foo;
grid-column-end: qoo;
grid-row-start: 2;
grid-row-end: 3;
}
/* 等同於 */
.grid-item {
grid-column-start: foo;
grid-column-end: qoo;
grid-row-start: -3;
grid-row-end: -2;
}
<數字> <自訂軌道名稱>
接著我們來聊 <數字> <自訂軌道名稱>
這個設定方式,他有一個先決條件,
當你的自訂軌道有複數相同的名稱時,此設定才會正常,不然一樣會觸發隱性軌道的設置。
我們舉幾個例子來看看,
.grid-container {
display: grid;
grid-template-columns: repeat(7, [foo] 1fr [qoo]);
grid-template-rows: repeat(3, 1fr);
grid-auto-rows: 100px;
}
接著我們來看比較正常定義的狀態,
.grid-item-a {
grid-column-start: foo;
grid-column-end: 2 qoo;
grid-row: auto;
}
好的,根據 <數字> <自訂軌道名稱>
的定義,我們的欄方向結束軌道是 第二個 qoo,所以你知道最後我們的網格單元會在那個位置上了嗎?
如果算錯了怎麼辦?舉個例子來說,
.grid-item-b {
grid-column-start: -3 foo;
grid-column-end: -4 qoo;
grid-row: auto;
}
阿我就怕被罵啊。
如果起始與結束在同一個網格軌道上,網格單元會自動往 下一個軌道空間擺放。
所以,剛剛寫錯的地方,他其實就是以下這樣的設定方式,
.grid-item-b {
grid-column-start: -3 foo;
grid-column-end: -3 qoo;
grid-row: auto;
}
無論你的數字是正值還是負值,基本上遇到一樣的狀況時,網格系統就是會這樣去做處理。如果沒空間可以放的話,那麼就會出現隱性網格軌道,用來擺放應該放進去的位置。舉例來說,
/* 超出網格容器的軌道數量 */
.grid-item-b {
grid-column-start: -9 foo;
grid-column-end: 12 qoo;
grid-row: auto;
}
圖片我就不放了,上面設定的結果就是你會獲得 12 條軌道。至於為什麼不要問我,稍微加點乘除一下就會知道了。
span [<數字>, <自訂軌道名稱>]
最後一種設定方式稱之為跨度(跨維度)的 Grid 單元設定。所謂的跨維度,意思就是你可以指定你要 跨過 多少個軌道,
span 3
表示跨過三個軌道span foo
表示跨過命名軌道foo
這個關鍵字 span
有兩種不同的呈現方式,你把他放在 -start
與 -end
的兩種位置上時,他的操作方式會略有不同。我們先來看看使用 -end
的狀況,他比較容易理解,
.grid-item {
grid-column-start: 1;
grid-column-end: span 3;
grid-row: auto;
}
我們在 grid-column-end
的設定是 span 3
,他的意思就是,
從
grid-column-start
的設定開始,欄方向 往後 做跨度 3 個軌道的動作。如果是命名軌道,則是欄方向 往後 做 跨度直到<命名軌道>
的動作。
用數字的方式很容易理解,如果今天使用的是 <命名軌道>
呢?跟往常在使用命名軌道的邏輯是相同的,他只會計算 符合名稱的軌道,換句話說,如果他找不到你的軌道名稱,那麼就會觸發隱性軌道的事件發生。
我們先不談隱性軌道,單純以合法的方式來操作。在命名軌道的情況下,所謂的跨度的計算方式,在 -end
的設定方式下,他會往後找下一個符合命名軌道的軌道來做跨度的動作。所以,我們舉一個名稱比較多的軌道來當例子,會比較容易理解,
.grid-container {
display: grid;
grid-template-columns: [foo] 1fr [ooo] 1fr [ppp] 1fr [rrr] 1fr [boo] repeat(3, [foo] 1fr [qoo]);
grid-template-rows: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.grid-item:nth-of-type(1) {
grid-column-start: 1;
grid-column-end: span foo;
grid-row: auto;
}
.grid-item:nth-of-type(2) {
grid-column-start: zoo;
grid-column-end: span qoo;
grid-row: auto;
}
以上是使用在 -end
的情況,這個設定換成 grid-row-*
也是一樣的,你就把他想成換了一個方向就可以了。
接著來談談 -start
配上 span
這件事情,或許你會覺得困惑,所謂的跨度不就是 往後跨格線軌道 這樣嗎?理論上對,但這是在 -end
的情況下,如果使用在 -start
的話,就會變成 往前跨格線軌道 的操作方式,是的,方向跟 -end
相反。
-end
使用span
是 往後跨度。
-start
使用span
是 往前跨度。
如果可以理解的話,那麼以下兩種設定就只要瞭解 -end
的概念,然後把方向 反過來 就可以了,
grid-column-start: span 3
從grid-column-end
軌道 往前 跨度 3 個軌道。grid-column-start: span boo
從grid-column-end
軌道 往前 跨度到boo
軌道。
所以,如果這樣使用會是什麼呈現方式呢?我用剛剛的 grid-column-end
的例子,然後把他做成 grid-column-start
的寫法,然後 Grid 單元呈現會完全一樣。
以上就是 span
關鍵字的相關用法。我這邊沒有提到異常的處理方式,之後有機會再拿回來講。畢竟,如果你只有 8 條格線軌道,你故意要跨 10 條軌道本來就會壞掉。所以這種情況我們暫時不在這裡提,隱性軌道的事情講起來太煩悶了。之後再來提會產生隱性軌道的事情吧。
關於 auto
與 Grid 單元軌道重疊
當你在設定一個比較複雜的格線系統時,可能有機會 算錯軌道 或是 打錯軌道名字 ,造成某些 Grid 單元在格線軌道設定的地方產生重疊。而這個重疊狀況,就會產生兩個單元互相覆蓋的情形。
.grid-container {
display: grid;
grid-template-columns: [foo] 1fr [ooo] 1fr [ppp] 1fr [rrr] 1fr [boo] repeat(3, [foo] 1fr [qoo]);
grid-template-rows: repeat(3, 1fr);
grid-auto-rows: 100px;
}
.grid-item:nth-of-type(1) {
grid-column-start: 1;
grid-column-end: 6;
/* 指定在第一列 */
grid-row: 1 / 2;
}
.grid-item:nth-of-type(2) {
grid-column-start: foo;
grid-column-end: span roo;
/* 指定在第一列 */
grid-row: 1 / 2;
}
在這種情況下,如果使用 auto
的話,又會有不一樣的事情發生了,這些情況還需要看你是否有搭配 span
使用,組合起來會有各種不一樣的事情發生。
grid-column-start |
grid-column-end |
結果 |
---|---|---|
auto |
3 |
定位在第 3 軌道,往前跨 1 個軌道,產生一個格線單元,並覆蓋相同位置的任何單元。 |
auto |
loo |
定位在 loo 軌道上,往前跨 1 個軌道,產生一個格線單元,並覆蓋相同位置的任何單元。 |
auto |
span 3 |
從上一個相同位置軌道的 最後一個軌道,往後跨 3 個軌道,產生一個格線單元。 |
auto |
span qoo |
此設置無效,僅會從上一個相同位置軌道的 最後一個軌道,往後跨 1 個軌道,產生一個格線單元。 |
1 |
auto |
定位在第 1 軌道,往後跨 1 個軌道,產生一個格線單元,並覆蓋相同位置的任何單元。 |
loo |
auto |
定位在 loo 軌道上,往後跨 1 個軌道,產生一個格線單元,並覆蓋相同位置的任何單元。 |
span 3 |
auto |
從上一個相同位置軌道的 最後一個軌道,往後跨 3 個軌道,產生一個格線單元。 |
span qoo |
auto |
此設置無效,僅會從上一個相同位置軌道的 最後一個軌道,往後跨 1 個軌道,產生一個格線單元。 |
以上的狀態換到 grid-row-*
也會是一樣的情況,僅方向不同而已。上述的情況我就不做圖片示意了,基本上稍微想像一下就好,我懶得作圖了(燦笑)。
官方沒有寫的例外
扣除 auto
與 span
之外,還有一種設定是合法的,但是 w3c 官方在這邊並沒有列出來,根據文件的部分也就如同我上面描述的東西而已,這個寫法是,
<自訂軌道名稱> <數字>
這個寫法等同於 <數字> <自訂軌道名稱>
,如果下次看到有人這樣寫不用太意外。算是冷知識說出來讓大家知道一下(笑)。
小記
這樣就結束了嗎?當然還有一點東西可以繼續嘴,對齊跟定位的問題我們明天會繼續講。
目錄與小節:
[CSS] Flex/Grid Layout Modules, part 0