> ## 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 3, Day 13
- URL: https://blog.hinablue.me/12th-ithome-ironman-day-13/
- Published: 2020-09-27T12:20:53.000Z
- Updated: 2026-07-06T18:40:09.000Z
- Author: Hina Chen
- Tags: Grid Layout, Grid System, CSS, ITHome, 鐵人賽, 2020, Media Query

## 間隔、間隔、間隔

先不囉唆，上圖。

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

中間看起來比較密集的部分，就是所謂的 **間隔**，在樣式表當中就是這樣設定，

```
.grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(4, 1fr);
    grid-gap: 1rem;
}

```

這邊能夠接受的數值除了 `fr` 不能用以外，其他數字你要怎麼寫都可以。你也可以把間隔設定的比元件尺寸還要大，但是應該不會有人做這種事情吧。那麼，這個間隔有什麼毛病呢？請你回去看看剛剛那張圖。

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

> 看到那個精美的內容衝到間隔裡面了嗎？

是的，這跟昨天在說明 Grid 規則跟尺寸的部分相同。他無法硬性規定你的元件不能超過格線軌道的尺寸限制，所以，你所設計的間隔如果遇到這種狀況，並不能真實反應兩個元件之間是否一定存在有這樣的間距。在這個時候，你是不是開始懷念 `float: left;` 然後 `margin: 0 15px` 這種設計了。

所以，從 `grid-template` 到 `grid-gap` 整組的容器大結構來看，基本上就是設計一個有格線軌道的容器，然後，然後就沒有然後了。不然你覺得 Grid Layout Module 還能做什麼事情呢？

> 好啦，我後面可以告訴你一些八奇的用法。

---

## 合併、重複與空區塊

在格線系統當中，有一個很特別的屬性，可以針對格線區塊來命名，

```
.grid {
    display: grid;
    grid-template-areas: 
        "head head head"
        "lefthand body lover"
        ". foot ."
}

```

我們沒有特別指定 `rows` 或 `columns`，直接使用 `grid-template-areas` 來指定需要的區塊，並且賦予他們名字，我們現在就來看看上面那樣的設定代表哪些事情。

- "head head head" 代表我有一個 `1 row x 3 columns` 的區塊，他們的 **名字都一樣**，表示他會變成 **合併儲存格**。
- "lefthand body righthand" 格線區塊同上，但是他們不會合併，是獨立的區塊。
- ". foot ." 格線區塊同上，但由於使用了 `.`，所以這個區塊不會被使用（變成空白區塊）。

所以，上面的設定就會變成一個 `3 x 3` 的格線容器。這個時候，倘若你設定了 `rows` 或 `columns` 的話，如果設定的容器比較大，就會從 `3 x 3` 長大，如果比 `areas` 設定的小，那麼最小就會使用 `3 x 3` 的格線容器。

![Grid Template Areas](https://ithelp.ithome.com.tw/upload/images/20200926/20001433kFdDxRC9BC.png)

接著，你要把容器元件放到 **指定名稱的區塊**，所以就會變成這樣的設定，

```
.grid .head {
    grid-area: head;
}
.grid .foot {
    grid-area: foot;
}
.grid .lefthand {
    /* 左手只是輔助 */
    grid-area: lefthand;
}
.grid .lover {
    grid-area: lover;
}
.grid .body {
    grid-area: body;
}

```

好的，如果說 **指定位置** 的動作在樣式表當中就做好了，那麼我 HTML 要做什麼？

> 就像你問男（女）朋友晚餐要吃什麼？
> 
> 隨便。

所以 HTML 可以這樣寫也沒關係，

```
<section class="grid">
    <div class="item foot"></div>
    <div class="item lover"></div>
    <div class="item body"></div>
    <div class="item lefthand"></div>
    <div class="item head"></div>
</section>

```

> 千萬不要，好嗎。

雖然格線系統的目的是讓你排版，但是不代表你可以惡搞 DOM 結構。另外，如果你用了一個沒有被命名的區塊，他還是會畫出來給你。你覺得他會放在哪裡？

```
<section class="grid">
    <div class="item foot"></div>
    <div class="item lover"></div>
    <div class="item body"></div>
    <div class="item lefthand"></div>
    <div class="item head"></div>
    <div class="item r20"></div>
</section>

```

```
.grid .r20 {
    grid-area: r20;
}

```

我先把結果放上來，然後你自己想想他放在什麼地方。

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

好的，這個放置位置就跟格線系統的填滿規則有關。當你的元件放在一個 **不存在** 的區塊，他會有兩種反應，

- 如果是命名區塊不存在或沒指定名稱，會先去放置到第一個空區塊，並依序把空區塊放滿。
- 如果空區塊都被放滿了，則依照格線稀疏排列方式繼續往下排列。
- 如果是元件指定位置，則會把格線軌道長大到那個尺寸，然後把元件放在那個位置上。

來，我們看看指定位置超出容器的狀況，

```
.grid .r20 {
    grid-column: 5 / 6;
    grid-row: 2 / 3;
}

```

最終你會得到這樣的結果，

![指定位置超出格線系統](https://ithelp.ithome.com.tw/upload/images/20200926/20001433FWe3AC6EXT.png)

你會得到一個 **變大** 的格線容器。好的，這樣可以理解空區塊，命名區塊跟超出容器設定的差異了吧。另外，在格線系統中，剛剛提到的間隔，每個間隔其實也可以命名，舉例來說，

```
.grid {
    grid-template-columns: [first] 1fr [two] 1fr [lala] 1fr [lol] 1fr [column-end];
    grid-template-rows: [hello] 1fr [r20] 1fr [world] 1fr [last] 1fr [row-end];
}

```

命名方式有很多種變形，例如可以多組名字，

```
.grid {
    grid-template-columns: [first] 1fr [first-end two] 1fr [two-end lala] 1fr [lol] 1fr [column-end];
    grid-template-rows: [hello] 1fr [r20] 1fr [world] 1fr [last] 1fr [row-end];
}

```

當中的 `[first-end two]` 就代表這個間隔有兩個名字。然後，

> `grid-template-columns` 跟 `grid-template-rows` 會覆蓋 `grid-template-areas` 的尺寸。

舉例來說，把剛剛上面的 `grid-template-areas` 合併起來看，

```
.grid {
    display: grid;
    grid-template-columns: [first] 1fr [two] 1fr [lala] 1fr [lol] 1fr [column-end];
    grid-template-rows: [hello] 1fr [r20] 1fr [world] 1fr [last] 1fr [row-end];
    grid-template-areas: 
        "head head head"
        "lefthand body lover"
        ". foot ."
}

```

他就會變成 `4 x 4` 然後中間有包含一個有命名的 `grid-template-areas`。然後，關於 `grid-template-columns` 跟 `grid-template-rows` 這邊有三種特殊設定可以使用，

- `span <命名間隔>` 跨過 `<命名間隔>` 的格線，直到碰觸到下一個格線為止。
- `span <數字 N>` 跨過 **指定數字 N 個間隔**。
- `<命名間隔> <負數 N>` 指到 `<命名間隔>` 後，**往回算 N 個間隔**。

請注意 `span` 的使用，如果指定到的 `<命名間隔>` 不存在，就會直接接到容器的最後面。如果 `<數字 N>` 加上開始格線，超過容器的尺寸，容器會直接被擴大。舉例來說，

```
.grid .r20 {
    grid-column-start: 1;
    grid-column-end: span 30;
    grid-row-start: 2;
    grid-row-end: span 29;
}

```

這樣你就會獲得 `30 x 30` 的容器。是的，容器本身並不會硬性規定可容納的區塊，倘若內部區塊設定有不符合的地方，那麼他就會自己擴充到剛好可以放得下的那個尺寸。這一點在規劃、設計格線系統元件時，需要特別留意。

或者你會說，那我就不要設定容器的尺寸就好啦，反正元件要長由他長，要跳位置就跳位置啊。

> 你一定是甲方派來臥底的對不對！

---

## 所以說那個手機版

所以當我們的行動裝置需要複雜規劃時，利用 Grid 來做一些相對複雜的卡片內容排版是合理的。只是說，通常也不會複雜到 Flex 無法應付的狀況。如果有的話，先看一下甲方的誠意再說。