我們先來看 Grid 的容器,他包含了 一張試算表 像是 Table 一樣的東西,為何會說他 像是 Table,我直接舉例給大家看就知道了,
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
}
.item1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
}
HTML 長這樣,
<section class="grid">
<div class="item item-1"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</section>
用 Table 來解釋,
/* 沒有 CSS */
<table>
<tbody>
<tr>
<td colspan="2" rowspan="2"></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>你是忘記了,還是害怕想起來</td>
</tr>
</tbody>
</table>
那就回去寫 Table 就好啦~我還可以支援 IE6/7/8/9/10/11 呢,好蚌蚌!
你走開,我暫時不想跟你說話。
好的,我們來看看 Grid 實際在瀏覽器裡面的狀況,
你在畫面中所看到的 虛線,就是 Grid 所排出來的 column
與 row
的線,然後你就會得到 4 x 4
總共 16
個區塊。然後第一個區塊看起來很空曠,那是因為紅色的內容寬度固定為 100x100
的關係。如果我們把第一個區塊放大到 600x600
的時候,他就會變成這個樣子,
他就會超過原本設定的區域,而,這件事情是不是可以避免?
不行。
無論你是故意還是不小心,讓容器元件內的尺寸,比你的 Grid 規則還要大,他是沒有方式可以限制他的展示區域的。這一點跟 Table 的操作是完全不同的。整體來說,Grid 在畫面上是一種虛擬的排版結構,並沒有 硬性規定 元件內容一定要跟著結構的尺寸走。
fr
這個單位是在 Grid 推出之後,跟著推出的一種尺寸標記方式。他的全名叫做 ,引用一下 w3c 對此單位的說明,
A flexible length or
<flex>
is a dimension with thefr
unit, which represents a fraction of the leftover space in the grid container. Tracks sized withfr
units are called flexible tracks as they flex in response to leftover space similar to how flex items with a zero base size fill space in a flex container.
翻成中文就是,
彈性元件在單一方向上面的相對尺寸單位。
說到相對尺寸,你可能會馬上聯想到 %
這個單位設定。不過基本上,他跟百分比的設定又稍微不一樣。我們用剛剛的例子來說明這個差異,如果我的容器是固定寬度與高度,那麼,我的格線軌道(Grid Track)一樣使用 4 x 4
,只是我們把單位換一下,換成 %
。根據上一個段落的例子,如果我們需要平均分配成 4 x 4
,那我們大概會知道就是 100% / 4
這樣的概念。
grid-template-columns: repeat(4, 25%);
好的,這樣看起來很合理。那麼,我們做一點比較騷包的操作,如果我想要的欄位格線軌道,是這樣的分配,
grid-template-columns: 2fr 1fr 1.5fr 1fr;
然後如果把他換成百分比,大概會是這樣,
grid-template-columns: 36.36% 18.18% 27.27% 18.18%;
然後畫出來就變成,
上面那個框框是使用百分比來定義,底下那個框框是使用 fr
單位定義。差異可能沒有很明顯,那麼,我們來做一個比較惡意的操作,
grid-template-columns: 20% 30% 40% 50%;
他會呈現這個結果,
來,我來解釋解釋上面發生了什麼事情,
800px
,則元件參照容器尺寸來呈現他的寬度。160px
, 240px
, 320px
與 400px
。800px
也無所謂,只要你的容器沒有 overflow: hidden
就不會被遮斷。以上是 寬度 的狀況,如果把方向轉成行(rows
)的話,他會有另一番風景,
height
)為 800px
的話(固定值),則運算規則跟寬度的方式相同。max-content
當作最大高度。好的,我實在不太想解釋百分比的事情,如果你很熱愛用百分比的話,
你走開,我暫時不想跟你說話。
如果你可以理解這個畫面的話,你繼續用百分比沒關係。
好了,我覺得我在百分比花了太多廢話,總之,在確認狀況之前,請勿濫用百分比。接著,如果用 fr
把剛剛的百分比反過來翻譯的話,他的狀況大概會是,
我想要分配 2 份、3 份、4 份與 5 份。
先給畫面,然後我再來解釋 fr
怎麼處理 幾份 這件事情。
在格線系統遇到無限大尺寸時(例如無高度設定容器),他會取出該格線軌道上(
rows
或columns
)的元件內容填充的尺寸,來當作基本尺寸,而這個基本尺寸 會取最大內容尺寸 來當基準(不要問我為何不是最小)。然後,就會使用這個最大內容尺寸當作1fr
來做計算。所以他的計算方式就是,
另外,如果這個 fr
的數字介於 0
到 1
之間的話,他會取決於上述提到的 leftover-space
,如果元件沒有剩餘任何空間,則會被強迫設定成最小容器元件的尺寸,在這個時候就很類似 min-content
的作法。但是!
但是!
強迫設定成
min-content
這個作法,是在無限大尺寸的狀況下會發生。
所以,你不要問我為何這個不是用 min-content
我會生氣!
grid-template-columns: 0.3fr 1fr 1fr 1fr;
任何橫向內容,你的裝置尺寸就是寬度天然屏障,不會有無限大尺寸的情況發生。
懂?
如果你把每個段落設定成 100vh
,然後做一下非同步捲軸,那麼你裡面的資料用 Grid 排也不是不行。畢竟所謂的「行動裝置」不僅僅只有手機,現在的電視也是行動裝置的一種,只是通常他不會動,然後通常會出現在客廳這樣而已。
Blog 同步刊登:[12th 鐵人賽] Grid 格線系統 Part 2, Day 12