> ## Content Index
> Fetch the complete content index at: https://blog.hinablue.me/llms.txt
> Use this file to discover other available public pages before exploring further.

# [12th 鐵人賽] Grid 格線系統 Part 2, Day 12
- URL: https://blog.hinablue.me/12th-ithome-ironman-day-12/
- Published: 2020-09-26T06:16:51.000Z
- Updated: 2026-07-06T18:40:16.000Z
- Author: Hina Chen
- Tags: CSS, Grid Layout, Grid System, Flexbox, ITHome, 鐵人賽, 2020

## 容器

我們先來看 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 實際在瀏覽器裡面的狀況，

![](https://blog.hinablue.me/content/images/2020/09/2020-12th-ironman-20.png)

你在畫面中所看到的 *虛線*，就是 Grid 所排出來的 `column` 與 `row` 的線，然後你就會得到 `4 x 4` 總共 `16` 個區塊。然後第一個區塊看起來很空曠，那是因為紅色的內容寬度固定為 `100x100` 的關係。如果我們把第一個區塊放大到 `600x600` 的時候，他就會變成這個樣子，

![](https://blog.hinablue.me/content/images/2020/09/2020-12th-ironman-21.png)

他就會超過原本設定的區域，而，這件事情是不是可以避免？

> 不行。

無論你是故意還是不小心，讓容器元件內的尺寸，比你的 Grid 規則還要大，他是沒有方式可以限制他的展示區域的。這一點跟 Table 的操作是完全不同的。整體來說，Grid 在畫面上是一種虛擬的排版結構，並沒有 *硬性規定* 元件內容一定要跟著結構的尺寸走。

---

## 新單位 `fr`

這個單位是在 Grid 推出之後，跟著推出的一種尺寸標記方式。他的全名叫做 [](https://www.w3.org/TR/css-grid-2/?ref=blog.hinablue.me#fr-unit)，引用一下 w3c 對此單位的說明，

> A *flexible length* or `<flex>` is a dimension with the `fr` unit, which represents a fraction of the leftover space in the grid container. Tracks sized with `fr` 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%;

```

然後畫出來就變成，

![](https://blog.hinablue.me/content/images/2020/09/2020-12th-ironman-22.png)

上面那個框框是使用百分比來定義，底下那個框框是使用 `fr` 單位定義。差異可能沒有很明顯，那麼，我們來做一個比較惡意的操作，

```
grid-template-columns: 20% 30% 40% 50%;

```

他會呈現這個結果，

![](https://blog.hinablue.me/content/images/2020/09/2020-12th-ironman-23.png)

來，我來解釋解釋上面發生了什麼事情，

- 由於你的容器有指定寬度，上述例子是 `800px`，則元件參照容器尺寸來呈現他的寬度。
- 容器的寬度換算出來，就分別是 `160px`, `240px`, `320px` 與 `400px`。
- 總和超過 `800px` 也無所謂，只要你的容器沒有 `overflow: hidden` 就不會被遮斷。
- 如果容器寬度是相對寬度，那麼這邊的容器尺寸就會繼續往外參考。
- 如果容器寬度最終參考到無限大（或基本上等於螢幕寬度），則以螢幕最大寬度為主。

以上是 **寬度** 的狀況，如果把方向轉成行（`rows`）的話，他會有另一番風景，

- 容器總高度（`height`）為 `800px` 的話（固定值），則運算規則跟寬度的方式相同。
- 如果高度為相對數值，則往外參考，基本上也跟寬度一樣的計算方式。
- 如果容器寬度最終參考到無限大（基本上網頁的設計就是沒有相對高度），則會用內容的 `max-content` 當作最大高度。

好的，我實在不太想解釋百分比的事情，如果你很熱愛用百分比的話，

> 你走開，我暫時不想跟你說話。

如果你可以理解這個畫面的話，你繼續用百分比沒關係。

![](https://blog.hinablue.me/content/images/2020/09/2020-12th-ironman-24.png)

好了，我覺得我在百分比花了太多廢話，總之，在確認狀況之前，請勿濫用百分比。接著，如果用 `fr` 把剛剛的百分比反過來翻譯的話，他的狀況大概會是，

> 我想要分配 2 份、3 份、4 份與 5 份。

先給畫面，然後我再來解釋 `fr` 怎麼處理 **幾份** 這件事情。

![](https://blog.hinablue.me/content/images/2020/09/2020-12th-ironman-25.png)

> 在格線系統遇到無限大尺寸時（例如無高度設定容器），他會取出該格線軌道上（`rows` 或 `columns`）的元件內容填充的尺寸，來當作基本尺寸，而這個基本尺寸 **會取最大內容尺寸** 來當基準（~~不要問我為何不是最小~~）。然後，就會使用這個最大內容尺寸當作 `1fr` 來做計算。
> 
> 所以他的計算方式就是，
> 
> [Find the Size of an fr](https://www.w3.org/TR/css-grid-2/?ref=blog.hinablue.me#leftover-space)

另外，如果這個 `fr` 的數字介於 `0` 到 `1` 之間的話，他會取決於上述提到的 `leftover-space`，如果元件沒有剩餘任何空間，則會被強迫設定成最小容器元件的尺寸，在這個時候就很類似 `min-content` 的作法。但是！

> 但是！
> 
> 強迫設定成 `min-content` 這個作法，是在無限大尺寸的狀況下會發生。

所以，你不要問我為何這個不是用 `min-content` 我會生氣！

```
grid-template-columns: 0.3fr 1fr 1fr 1fr;

```

> 任何橫向內容，你的裝置尺寸就是寬度天然屏障，不會有無限大尺寸的情況發生。
> 
> 懂？

---

## 所以說那個手機版

如果你把每個段落設定成 `100vh`，然後做一下非同步捲軸，那麼你裡面的資料用 Grid 排也不是不行。畢竟所謂的「行動裝置」不僅僅只有手機，現在的電視也是行動裝置的一種，只是通常他不會動，然後通常會出現在客廳這樣而已。