# Day 55：CSS 選擇器語法、層疊順序、Normal Flow、Position、Margin Collapsing、HTML/CSS vs JavaScript 除錯差異

By [雞蛋糕的前端修煉屋](https://paragraph.com/@gcake) · 2026-02-07

---

今日學習主題
------

*   CSS 選擇器語法與層疊優先級
    
*   Normal Flow 排版機制
    
*   Block vs Inline 元素特性
    
*   Position 定位與 z-index 堆疊
    
*   Margin Collapsing 規則
    
*   HTML/CSS vs JavaScript 除錯差異
    

* * *

CSS 選擇器與層疊順序
------------

### 從常見陷阱開始

**問題情境**:為什麼 `<a class="a b">HELLO</a>` 配上以下 CSS 會顯示紅色而非藍色?

    a { color: red; }
    b { color: blue; }
    

**答案揭曉**:因為 `b` 是**元素選擇器**,選中的是 `<b>` 標籤(如 `<b>粗體</b>`),而非 class="b"! [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

* * *

### 核心概念 1:元素選擇器 vs 類別選擇器

#### 元素選擇器(Element Selector)

直接使用 HTML 標籤名稱,**不需要任何前綴符號**: [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

    /* 選取所有 <a> 標籤 */
    a {
      color: red;
    }
    
    /* 選取所有 <p> 標籤 */
    p {
      font-size: 16px;
    }
    

#### 類別選擇器(Class Selector)

在 class 名稱前必須加上**點(.)符號**: [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

    /* 選取所有 class="menu" 的元素 */
    .menu {
      background: blue;
    }
    
    /* 選取所有 class="btn-primary" 的元素 */
    .btn-primary {
      padding: 10px;
    }
    

#### 對比表格

選擇器類型

語法

範例

選取目標

元素選擇器

`elementname`

`a`, `div`, `p`

HTML 標籤本身

類別選擇器

`.classname`

`.menu`, `.btn`

含有該 class 的元素

* * *

### 核心概念 2:HTML class 屬性的多類別語法

#### 空格是分隔符號

在 HTML 的 `class` 屬性中,**空格用來分隔多個類別名稱**: [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

    <!-- 這個 div 同時擁有兩個類別:primary 和 button -->
    <div class="primary button"></div>
    
    <!-- 這個 a 同時擁有三個類別:nav, link, active -->
    <a class="nav link active">Home</a>
    

#### 類別名稱本身不能有空格

單一類別名稱內部不能包含空格,需要多個單字時使用連字符號:

    <!-- ✓ 正確:使用 kebab-case -->
    <button class="btn-primary"></button>
    
    <!-- ✗ 錯誤:會被解讀成兩個類別 btn 和 primary -->
    <button class="btn primary"></button>
    

#### 選擇多個類別的 CSS 語法

    /* 選中所有 class="primary" 的元素 */
    .primary { color: red; }
    
    /* 選中所有 class="button" 的元素 */
    .button { padding: 10px; }
    
    /* 選中「同時擁有 primary 和 button」的元素(中間無空格) */
    .primary.button { border: 1px solid; }
    
    /* 選中「primary 裡面的 button」(中間有空格) */
    .primary .button { margin: 5px; }
    

* * *

### 核心概念 3:CSS 層疊順序(Cascade Order)

#### 層疊的運作原理

CSS 像油漆工在牆上一層層塗油漆,後塗的會覆蓋先塗的。 [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

#### 優先權判斷三步驟

當多條 CSS 規則衝突時,瀏覽器按照這個順序判斷: [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

1.  **優先級(Specificity)**:選擇器越精準,優先權越高
    
2.  **來源順序(Source Order)**:優先級相同時,後面的覆蓋前面的
    
3.  **重要性(!important)**:強制覆蓋所有規則(不建議濫用)
    

#### 優先級計算表

選擇器類型

優先級值

範例

說明

Inline style

1-0-0-0

`<div style="color:red">`

最高

ID

0-1-0-0

`#header`

高

Class / 偽類 / 屬性

0-0-1-0

`.menu`, `:hover`, `[type="text"]`

中

Element / 偽元素

0-0-0-1

`a`, `div`, `::before`

低

[w3schools](https://www.w3schools.com/css/css_specificity.asp)

#### 實例解析 1:優先級相同

    <a class="a b">HELLO</a>
    

    .a { color: red; }   /* 優先級:0-0-1-0 */
    .b { color: blue; }  /* 優先級:0-0-1-0 */
    

**結果**:藍色  
**原因**:兩個選擇器優先級相同,`.b` 在後面所以覆蓋 `.a` [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

#### 實例解析 2:優先級不同

    <a class="a b">HELLO</a>
    

    a.b { color: blue; }  /* 優先級:0-0-1-1 (1個元素+1個類別) */
    .a { color: red; }    /* 優先級:0-0-1-0 (1個類別) */
    

**結果**:藍色  
**原因**:`a.b` 優先級較高,不管 CSS 出現順序 [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

* * *

### 原始題目完整解析

**題目**:

    <a class="a b">HELLO</a>
    

    a{ color:red }
    b{ color:blue }
    

**拆解過程**:

1.  **HTML 解讀**:這是一個 `<a>` 標籤,同時擁有兩個類別:`a` 和 `b`
    
2.  **CSS 解讀**:
    
    *   `a{ color:red }` 是**元素選擇器**,選中所有 `<a>` 標籤 ✓
        
    *   `b{ color:blue }` 是**元素選擇器**,選中所有 `<b>` 標籤(如 `<b>粗體</b>`) ✗
        
3.  **結果**:只有第一條規則套用,顯示**紅色**
    

**正確寫法**:

    a{ color:red }     /* 選中 <a> 標籤 */
    .b{ color:blue }   /* 選中 class="b" 的元素 */
    

這時兩條規則都會套用,`.b` 優先級較高,最終顯示藍色。

* * *

### 易錯提醒

#### 1\. 類別選擇器忘記加點

    /* ✗ 錯誤:這是選 <menu> 標籤,不是 class="menu" */
    menu { color: red; }
    
    /* ✓ 正確:這才是選 class="menu" */
    .menu { color: red; }
    

#### 2\. 混淆元素與類別

    b { color: blue; }   /* 選 <b> 標籤 */
    .b { color: blue; }  /* 選 class="b" */
    

#### 3\. HTML class 順序不影響結果

    <!-- 這兩個完全一樣 -->
    <div class="a b"></div>
    <div class="b a"></div>
    

CSS 規則的**出現順序**才會影響層疊結果,HTML 中 class 的順序無關。

#### 4\. 多類別選擇器的空格差異

    .a.b { }   /* 同時擁有 a 和 b 類別的元素 */
    .a .b { }  /* a 類別元素裡面的 b 類別元素 */
    

* * *

Normal Flow:元素排列的預設規則
---------------------

\*\*Normal Flow(正常流)\*\*是瀏覽器排版的預設模式,所有「佔空間」的元素都在這個流程裡排隊。在 normal flow 中,元素只有兩種排列方式:**block(區塊級)** 或 **inline(行內級)**。 [docs3.w3cub](https://docs3.w3cub.com/css/css_flow_layout/block_and_inline_layout_in_normal_flow/)

* * *

### Block 元素:垂直堆疊的排版框

#### 排列規則

**Block 元素會「獨佔一整行」,一個接一個垂直往下堆疊**。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

    <div>第一個區塊</div>
    <p>第二個區塊</p>
    <div>第三個區塊</div>
    

**視覺結果**:

每個 block 元素自動換行,就算內容很短也會佔滿父元素的寬度。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

#### Block 元素的特性

特性

說明

**寬度**

預設佔滿父元素 100% 寬度

**高度**

由內容撐起,可設定 `height`

**可設定尺寸**

`width`、`height` 都有效

**可設定留白**

`margin`、`padding` 四個方向都有效

**換行**

前後都會自動換行

#### 常見的 Block 元素

*   `<div>` - 通用容器
    
*   `<p>` - 段落
    
*   `<h1>` ~ `<h6>` - 標題
    
*   `<ul>` `<ol>` `<li>` - 列表
    
*   `<section>` `<article>` `<header>` `<footer>` - 語意化容器
    

* * *

### Inline 元素:水平並排的文字流

#### 排列規則

**Inline 元素會「在同一行內橫向排列」,像文字一樣左右相鄰,遇到容器邊界才換行**。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

    <span>第一段</span>
    <strong>第二段</strong>
    <a href="#">連結</a>
    

**視覺結果**:

所有 inline 元素會擠在同一行,除非容器寬度不夠才會自動換行。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

#### Inline 元素的特性

特性

說明

**寬度**

只佔內容所需的寬度

**高度**

由內容撐起,**無法設定** `height`

**可設定尺寸**

`width`、`height` **都無效**

**可設定留白**

`margin`、`padding` **只有左右有效,上下無效**

**換行**

不會自動換行,和其他 inline 元素排在同一行

#### 常見的 Inline 元素

*   `<span>` - 通用行內容器
    
*   `<a>` - 超連結
    
*   `<strong>` `<em>` - 文字強調
    
*   `<img>` - 圖片(特殊的 inline 元素)
    
*   `<input>` `<button>` - 表單元素
    

* * *

### Normal Flow 的核心規則

#### 1\. Block 元素參與 Block Formatting Context

*   垂直方向一個接一個堆疊
    
*   上下 margin 會發生「margin collapsing(合併)」
    
*   寬度預設是父元素的 100%
    

[udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

#### 2\. Inline 元素參與 Inline Formatting Context

*   水平方向左右並排
    
*   遵循文字排版規則(對齊基線、響應 `text-align`)
    
*   寬度由內容決定,無法手動設定
    

[udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

#### 3\. Block 可以包含 Inline,但 Inline 不能包含 Block

    <!-- ✅ 正確:Block 包 Inline -->
    <div>
      這是段落,裡面有 <span>行內元素</span>。
    </div>
    
    <!-- ❌ 錯誤:Inline 包 Block -->
    <span>
      <div>區塊元素</div> <!-- 語意錯誤,瀏覽器可能修正 -->
    </span>
    

* * *

### Display 屬性:改變元素在 Normal Flow 的行為

雖然 HTML 元素有預設的 block/inline 屬性,但可以用 CSS 的 `display` 改變: [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

    /* 把 inline 元素改成 block */
    span {
      display: block; /* 現在 span 會獨佔一行 */
      width: 200px;   /* 可以設定寬度了 */
    }
    
    /* 把 block 元素改成 inline */
    div {
      display: inline; /* 現在 div 會並排 */
      width: 200px;    /* 無效,因為 inline 不能設定寬度 */
    }
    

#### 常用的 Display 值

值

行為

適用情境

`block`

獨佔一行,可設定寬高

容器、區塊佈局

`inline`

並排同行,不可設定寬高

文字樣式、小標籤

`inline-block`

並排同行,**但可設定寬高**

按鈕、卡片並排

`none`

完全隱藏,不佔空間

條件顯示

* * *

### Inline-Block:兼具兩者優點

`display: inline-block` 是特殊的混合模式: [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

    .button {
      display: inline-block;
      width: 100px;      /* 可以設定寬高(像 block) */
      height: 40px;
      padding: 10px;     /* 上下 padding 有效 */
      margin: 10px;      /* 上下 margin 有效 */
      /* 但會和其他元素並排(像 inline) */
    }
    

**特性**:

*   對外:像 inline 一樣橫向排列,不會換行
    
*   對內:像 block 一樣可以設定寬高和四方向留白
    

**常見用途**:導覽列按鈕、圖標並排、響應式卡片佈局。

* * *

Position 與 z-index:脫離 Normal Flow
---------------------------------

### 佔空間 vs 不佔空間

CSS 的「佔空間 / 不佔空間」,其實是在講元素有沒有**參與正常排版流程(normal flow)**。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

#### 什麼是「佔空間」(在 normal flow 裡)

在 **normal flow** 裡,元素會跟其他元素「排隊、互相推擠」。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

*   一個 block 元素(例如 `<div>`) 會一個接一個往下堆疊
    
*   調整它的 `margin`、`padding`、`height` 時,其他元素會跟著被推開或被擠下去
    
*   這種情況,我們就說:這個元素**有佔版面空間**,是 **in flow** 的元素
    

#### 什麼是「不佔空間」(被拿出 normal flow)

當元素被設成 `position: absolute` 或 `position: fixed` 時,會被**移出 normal flow**。 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

*   瀏覽器排版其他元素時,**完全當它不存在**
    
*   它原本在 normal flow 要站的位置,會被後面的元素填補上來
    
*   它的位置改由 `top / right / bottom / left`(配合最近的定位父元素或視窗)決定
    

### z-index:便利貼的「圖層順序」

當多張便利貼重疊時,`z-index` 決定**誰在上面、誰在下面**。

    .note-1 {
      position: absolute;
      z-index: 1; /* 比較低,會在下層 */
    }
    
    .note-2 {
      position: absolute;
      z-index: 10; /* 數字越大越上層 */
    }
    

**數字越大,越在上面**。可以用負數讓元素沉到更下層。

#### 重要限制:只對「定位元素」有效

`z-index` **只對有設定** `position` **的元素才會作用**(除了 `position: static`)。

    /* ❌ 無效:沒有設定 position */
    .box {
      z-index: 999; /* 不會有任何效果 */
    }
    
    /* ✅ 有效:搭配定位屬性 */
    .box {
      position: relative; /* 或 absolute / fixed / sticky */
      z-index: 999;      /* 現在才有效 */
    }
    

#### 堆疊上下文(Stacking Context):便利貼的「群組規則」

當父元素設定了 `position` + `z-index` 時,會建立一個**堆疊上下文(stacking context)**。

**關鍵規則**:子元素的 `z-index` **只在父元素的群組內比較**,無法跨群組競爭。

* * *

Margin Collapsing:垂直外距合併
------------------------

### 什麼時候會發生 margin Collapsing

只會發生在**垂直的上下 margin**,而且元素要在 **normal flow 的 block 排版裡**。 [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)

#### 1\. 同一層 block 兄弟元素相鄰

    <p class="a">段落 A</p>
    <p class="b">段落 B</p>
    

    .a {
      margin-bottom: 20px;
    }
    
    .b {
      margin-top: 40px;
    }
    

你可能以為 A 和 B 之間距離 = 20 + 40 = 60px,  
實際上**只會是 40px(較大的那個)**,這就叫「margin 重疊(collapsing)」。 [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)

> 規則:同一層、彼此相鄰、都是 block、沒有東西隔開(沒有邊框、padding、別的元素),上下 margin 就會合成一個,取最大值。 [geeksforgeeks](https://www.geeksforgeeks.org/css/what-are-the-rules-of-margin-collapse-in-css/)

#### 2\. 父元素和第一個/最後一個子元素之間

    <div class="parent">
      <p class="child">文字</p>
    </div>
    

    .parent {
      margin-top: 50px;
      /* 沒有 padding-top、border-top、高度/內容 */
    }
    
    .child {
      margin-top: 30px;
    }
    

*   這時你畫面最上方看到的**外距不是 50 + 30**
    
*   而是 **max(50, 30) = 50px**,等於子元素的 margin 被「傳到」父元素外面去了
    

[developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)

#### 3\. 空的 block 元素上下 margin 自己重疊

    .box {
      margin-top: 30px;
      margin-bottom: 50px;
      /* 沒有內容、沒有 padding、沒有 border、高度自動 */
    }
    

這個 `.box` 的上、下 margin 會互相重疊,變成一個 **50px 的外距**(取較大)。 [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)

#### 4\. 什麼情況「不會」重疊

*   左右方向的 margin(永遠不會重疊) [geeksforgeeks](https://www.geeksforgeeks.org/css/what-are-the-rules-of-margin-collapse-in-css/)
    
*   `display: flex` 或 `grid` 裡的子元素 margin [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)
    
*   `position: absolute` / `position: fixed` / 浮動元素的 margin [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)
    
*   被 `padding`、`border` 或非空內容隔開時 [joshwcomeau](https://www.joshwcomeau.com/css/rules-of-margin-collapse/)
    

* * *

### 跟「實體排版計算」的關聯:為什麼要設計成會重疊?

可以用「書頁排版」來比喻 margin 的設計思路:

#### 1\. 把「段落間距」當成一個概念(而不是兩個分開加總)

在排版一頁文章時,兩個段落之間通常會設計一個「段落間距」,而不是「上一段底下 10pt + 下一段上面 10pt = 合起來 20pt」,否則越多段落,間距越誇張。 [joshwcomeau](https://www.joshwcomeau.com/css/rules-of-margin-collapse/)

> CSS 設計者選擇:「如果上下兩個 margin 碰在一起,就把它視為**一個段落間距**」→ 所以只取最大那個,不做相加。 [joshwcomeau](https://www.joshwcomeau.com/css/rules-of-margin-collapse/)

#### 2\. 避免巢狀結構讓間距意外變大

實體排版如果一個段落包在框裡(例如卡片),你通常希望「外框 + 內文」整體看起來的段落間距**還是符合版面設計**,而不是框裡的 margin 又加一層父容器 margin。 [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)

* * *

### 實務開發的心智模型整理

1.  **margin 重疊只發生在「垂直、block、normal flow」這個世界裡**。 [geeksforgeeks](https://www.geeksforgeeks.org/css/what-are-the-rules-of-margin-collapse-in-css/)
    
2.  如果你看到「為什麼我設很多 margin,間距卻沒想像中大」,90% 是重疊在一起了。
    
3.  要「打斷」重疊,可以在中間加任何一層「墊片」:
    
    *   `padding`
        
    *   `border`
        
    *   實際內容(哪怕是一個看不到的 `::before`)
        
    *   或把那個容器變成 `flex`/`grid`
        

[joshwcomeau](https://www.joshwcomeau.com/css/rules-of-margin-collapse/)

* * *

HTML/CSS vs JavaScript:語言特性與除錯差異
--------------------------------

### 核心觀念

HTML/CSS 和 JavaScript 屬於完全不同類型的語言,這決定了它們的錯誤處理機制和除錯方式。

特性

HTML/CSS

JavaScript

**語言類型**

宣告式(Declarative)

命令式(Imperative)

**錯誤處理**

忽略無效規則,繼續執行

拋出錯誤,中斷執行

**IDE 支援**

靠規則比對提示

直接從引擎獲得錯誤

**除錯方式**

視覺檢查 + DevTools

Console 錯誤訊息 + Debugger

* * *

### HTML/CSS:宣告式語言

#### 運作邏輯

你只是「描述想要的結果」,瀏覽器會盡力實現,遇到錯誤**不會中斷執行**。

**比喻**:像「許願清單」,店員盡量滿足,但缺貨時會跳過繼續處理下一項,不會因為一個錯誤就罷工。

#### CSS 錯誤處理規範

    /* 瀏覽器遇到無效屬性會直接忽略,繼續套用其他規則 */
    .box {
      colur: red;      /* 拼字錯誤 → 瀏覽器忽略 */
      color: blue;     /* 正確語法 → 套用 ✓ */
      widht: 100px;    /* 拼字錯誤 → 瀏覽器忽略 */
      height: 100px;   /* 正確語法 → 套用 ✓ */
    }
    

**CSS 規範明確規定**:瀏覽器必須忽略無效的屬性/值,不會拋出任何錯誤訊息。這是設計選擇,確保即使開發者寫錯,使用者仍能看到網頁內容(容錯性 fault tolerance)。

* * *

### JavaScript:命令式語言

#### 運作邏輯

你下達「執行步驟」,引擎必須逐行執行,遇到錯誤會**立即拋出例外並中斷**。

**比喻**:像「煮菜食譜」,每一步都要正確執行,缺了鹽就會報錯停止,不會繼續煮下去。

#### JS 錯誤處理機制

    // 1. 語法錯誤(SyntaxError) - 執行前就會偵測
    const user = nul;  // ❌ SyntaxError: Unexpected token
    console.log(user); // 這行不會執行
    
    // 2. 執行時錯誤(Runtime Error)
    const user = null;
    console.log(user.name);  // ❌ TypeError: Cannot read property 'name' of null
    
    // 3. 錯誤捕捉機制
    try {
      riskyOperation();
    } catch (error) {
      console.error('捕捉到錯誤:', error.message);
      // 程式可以繼續執行
    }
    

* * *

### DevTools 檢查元素:五大核心功能

#### 1\. 追蹤樣式覆蓋(Override)

**用途**:找出「為什麼我寫的樣式沒生效」

    /* 在 Styles 面板會看到: */
    .button {
      color: blue;     /* 被刪除線蓋掉 */
    }
    
    #submit-btn {
      color: red;      /* ✓ 生效,因為 ID 權重更高 */
    }
    

**操作**:被刪除線劃掉的屬性就是被覆蓋的規則。

#### 2\. 查看權重/特異性(Specificity)

**用途**:解釋「為什麼這條規則贏了」

**權重計算規則**: [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)

    (a, b, c)
    a = ID 選擇器數量
    b = class/屬性/偽類選擇器數量
    c = 標籤選擇器數量
    

**操作**:滑鼠懸停在選擇器上,DevTools 會顯示權重計算。

#### 3\. 查看計算樣式(Computed)

**用途**:看到最終生效的值(經過繼承、覆蓋、預設值計算後)

**使用時機**:當 Styles 面板規則太多看不出問題時,直接看 Computed 找到最終值,再點擊展開追蹤來源。

#### 4\. 即時修改測試

**用途**:快速試錯,不用重新載入

**實務流程**:

1.  右鍵點擊元素 → 檢查
    
2.  在 Styles 面板點擊屬性值
    
3.  修改數值,瀏覽器立即套用
    
4.  確認效果後,回去改原始 CSS 檔案
    

**注意**:DevTools 的修改是**暫時的**,重新整理會消失!

#### 5\. 視覺化佈局工具

*   **Box Model 檢視器**:查看元素實際的 margin、border、padding、content
    
*   **Flexbox/Grid 檢視器**:顯示 flex items 對齊狀況、grid cells 佈局
    
*   **偽類狀態切換**:強制觸發 `:hover`、`:focus`、`:active` 等狀態
    

* * *

重點整理
----

### Normal Flow 的三個層級

1.  **Normal Flow(正常流)**:元素預設的排版系統 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)
    
2.  **Block Formatting Context**:block 元素垂直堆疊的規則 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)
    
3.  **Inline Formatting Context**:inline 元素水平並排的規則 [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)
    

### 記憶口訣

*   **Block = 獨佔一行的框**:可設定寬高,垂直堆疊
    
*   **Inline = 並排的文字流**:不可設定寬高,水平排列
    
*   **Inline-Block = 並排的框**:兼具兩者優點
    

### 脫離 Normal Flow 的方法

只要設定以下屬性,元素就會離開 normal flow: [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)

*   `position: absolute` 或 `fixed`
    
*   `float: left` 或 `right`
    
*   `display: flex` 或 `grid`(子元素會進入新的排版上下文)
    

* * *

延伸學習資源
------

*   [MDN - CSS Selectors](https://developer.mozilla.org/zh-TW/docs/Web/CSS/CSS_selectors)
    
*   [MDN - Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascade/Specificity) [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity.)
    
*   [MDN - Margin Collapsing](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing) [developer.mozilla](https://developer.mozilla.org/zh-TW/docs/Web/CSS/Guides/Box_model/Margin_collapsing)
    
*   [MDN - Normal Flow](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_display/Flow_layout) [udn.realityripple](https://udn.realityripple.com/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow)
    
*   [CSS Specificity Calculator](https://cssbootcamp.com/css/specificity-calculator) [cssbootcamp](https://cssbootcamp.com/css/specificity-calculator)
    
*   [The Rules of Margin Collapse](https://www.joshwcomeau.com/css/rules-of-margin-collapse/) [joshwcomeau](https://www.joshwcomeau.com/css/rules-of-margin-collapse/)
    

* * *

**筆記時間**:2026-02-06  
**核心學習**:CSS 選擇器語法、層疊順序、Normal Flow、Position、Margin Collapsing、HTML/CSS vs JavaScript 除錯差異  
**學習階段**:Phase 2 - JavaScript 基礎 + CSS 切版

---

*Originally published on [雞蛋糕的前端修煉屋](https://paragraph.com/@gcake/day-55)*
