關於自動這件事

我們昨天有提到 dense 這件事情,我們今天繼續腦補一下這個東西該怎麼把玩。首先,先以一個簡單的例子來開場,這是沒有使用 dense 的設定所產生的畫面,

在這邊我們只有把 .item-2.item-3 動過手腳,

.grid .item-2 {
    grid-row: 1 / span 2;
    grid-column: 1 / span 3;
    background: orange;
}
.grid .item-3 {
    grid-row: auto / span 2;
    grid-column: auto / span 3;
}

好的,請留意上面我所指定的 auto。在這裡的意思就是,不指定 開始位置,讓他自己找地方放。所以,在預設的稀疏排列方式的情況下,就會產生剛剛圖片中的畫面。接著,我們在容器內加上 dense 這個設定。

.grid {
    grid-auto-flow: row dense;
}

然後再次回到那個畫面,他就會變成這樣,

請注意,這邊有一個 先決條件,就是你的 grid-rowgrid-column 不能明確指定放置的位置,什麼叫做明確指定?以下都算是明確指定位置,

  • grid-row: 1 / span 2;
  • grid-column: 2 / 3;
  • grid-column: -1;
  • grid-row-start: 1;grid-row-end: 3
  • grid-column-start: first-line;grid-column-end: overload;
  • grid-area: 1 / 2 / 3 / 2;

然後比較曖昧的地方是,以下 不算是 明確指定位置,

  • grid-row: span 3;
  • grid-area: first / span 2 / 2 / span 2;

然後 grid-area 有個雷點,這邊 w3c 有解釋,

When grid-column-start is omitted, if grid-row-start is a , all four longhands are set to that value. Otherwise, it is set to auto.

所以剛剛那個 不算是 的地方,是因為他 失效 了所以跟本無法指定明確位置,並不是真的是沒有指定明確位置的狀態。

好的,這個就是目前所謂的 緊湊排列 的效果。他有幾個可以參考的設定方向,

  • 你的容器允許 擴充,或確認你的元件 不會超出 容器尺寸。
  • 盡可能不要設定 grid-auto-columngrid-auto-row 的尺寸。
  • dense 預設的方向是 row,所以 row densedense 效果一樣。
  • 如果你的 .item-* 都沒指定位置,等同於 grid-rowgrid-column 都是 auto
  • 你的元件 順序 會依照你的 DOM 的順序來排,除非你指定 order

再次提醒一個雷點,order 會干擾自動填滿的順序,請看以下範例,

好的,那我要怎麼知道我的元件會被 到哪個位置?

你可以一直重新整理瀏覽器,直到位置對了(欸)。

實際上,你若知道你的區塊尺寸,用手繪的方式可以大概推算會跑到什麼地方。這個沒有很明確的方法能判斷他 一定 會跑到你想要的位子上,畢竟決定某個空區域能不能放得下你的元件的人,是瀏覽器,不是你設定好樣式他就真的會這樣跑。


新的運算方式

除了從 Flex 就開始講的 fr 之外,打從 Flex 開始就有一些新的運算方式跟關鍵字可以使用,

屬性 說明
max-content 容器區塊內,元件的最大尺寸。
min-content 容器區塊內,元件的最小尺寸。
fit-content(<length-percentage>) 利用公式算出一個最緊湊的尺寸。在 w3c 規範的公式為:min(maximum size, max(minimum size, argument))
minmax(min, max) 指定容器區塊的最小、最大尺寸。
repeat([integer | auto-fill | auto-fit], <line-names>+) 自動重複所指定的格線軌道設定。

好的,我要開始講不能亂用的部分了。

  • repeat 如果後面帶著命名的格線軌道,會一起重複喔 (啾咪)
  • repeat 如果使用命名格線軌道,最後面不是數字,頭尾重疊會合併。
  • repeat 不能 repeat 自己。
  • auto-fill, auto-fit 不能跟 min-content, max-content, auto, fit-content 以及 fr 混用。
  • subgrid 目前還在 吵架 WD,只有 Firefox 率先支援。

來舉一些大量的範例。

.grid {
    grid-template-column: repeat(5, 1fr);
}
.grid {
    grid-template-column: 200px fit-content(1fr) max-content;
}
.grid {
    grid-template-column: repeat(auto-fill, minmax(25ch, 1fr));
}
.grid {
    grid-template-column: auto minmax(min-content, 1fr);
}
.grid {
    grid-template-column: repeat(3, [a] 2fr [b]);
}

最後一個特別說明一下,剛剛有提到 合併 這件事,上面那個 repeat 在實際上就會變成,

[a] 2fr [b a] 2fr [b a] 2fr [b]

所以說那個手機版

我說一句老實話,格線系統會難用就是因為上面那些奇妙的規則。然後實際上你並沒有辦法很準確的預測,到底 minmax 或是 fit-content 會出現什麼樣的效果。這跟 font-size: 20rem; 會有爆幹大的文字是不同層次的事情。