) 會一個接一個往下堆疊調整它的 margin、padding、height 時,其他元素會跟著被推開或被擠下去這種情況,我們就說:這個元素有佔版面空間,是 in flow 的元素什麼是「不佔空間」(被拿出 normal flow)當元素被設成 position: absolute 或 position: fixed 時,會被移出 normal flow。 udn.realityripple瀏覽器排版其他元素時,完全當它不存在它原本在 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.mozilla1. 同一層 block 兄弟元素相鄰
段落 A
段落 B
.a { margin-bottom: 20px; } .b { margin-top: 40px; } 你可能以為 A 和 B 之間距離 = 20 + 40 = 60px, 實際上只會是 40px(較大的那個),這就叫「margin 重疊(collapsing)」。 developer.mozilla規則:同一層、彼此相鄰、都是 block、沒有東西隔開(沒有邊框、padding、別的元素),上下 margin 就會合成一個,取最大值。 geeksforgeeks2. 父元素和第一個/最後一個子元素之間
.parent { margin-top: 50px; /* 沒有 padding-top、border-top、高度/內容 */ } .child { margin-top: 30px; } 這時你畫面最上方看到的外距不是 50 + 30而是 max(50, 30) = 50px,等於子元素的 margin 被「傳到」父元素外面去了developer.mozilla3. 空的 block 元素上下 margin 自己重疊.box { margin-top: 30px; margin-bottom: 50px; /* 沒有內容、沒有 padding、沒有 border、高度自動 */ } 這個 .box 的上、下 margin 會互相重疊,變成一個 50px 的外距(取較大)。 developer.mozilla4. 什麼情況「不會」重疊左右方向的 margin(永遠不會重疊) geeksforgeeksdisplay: flex 或 grid 裡的子元素 margin developer.mozillaposition: absolute / position: fixed / 浮動元素的 margin developer.mozilla被 padding、border 或非空內容隔開時 joshwcomeau跟「實體排版計算」的關聯:為什麼要設計成會重疊?可以用「書頁排版」來比喻 margin 的設計思路:1. 把「段落間距」當成一個概念(而不是兩個分開加總)在排版一頁文章時,兩個段落之間通常會設計一個「段落間距」,而不是「上一段底下 10pt + 下一段上面 10pt = 合起來 20pt」,否則越多段落,間距越誇張。 joshwcomeauCSS 設計者選擇:「如果上下兩個 margin 碰在一起,就把它視為一個段落間距」→ 所以只取最大那個,不做相加。 joshwcomeau2. 避免巢狀結構讓間距意外變大實體排版如果一個段落包在框裡(例如卡片),你通常希望「外框 + 內文」整體看起來的段落間距還是符合版面設計,而不是框裡的 margin 又加一層父容器 margin。 developer.mozilla實務開發的心智模型整理margin 重疊只發生在「垂直、block、normal flow」這個世界裡。 geeksforgeeks如果你看到「為什麼我設很多 margin,間距卻沒想像中大」,90% 是重疊在一起了。要「打斷」重疊,可以在中間加任何一層「墊片」:paddingborder實際內容(哪怕是一個看不到的 ::before)或把那個容器變成 flex/gridjoshwcomeauHTML/CSS vs JavaScript:語言特性與除錯差異核心觀念HTML/CSS 和 JavaScript 屬於完全不同類型的語言,這決定了它們的錯誤處理機制和除錯方式。特性HTML/CSSJavaScript語言類型宣告式(Declarative)命令式(Imperative)錯誤處理忽略無效規則,繼續執行拋出錯誤,中斷執行IDE 支援靠規則比對提示直接從引擎獲得錯誤除錯方式視覺檢查 + DevToolsConsole 錯誤訊息 + DebuggerHTML/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(a, b, c) a = ID 選擇器數量 b = class/屬性/偽類選擇器數量 c = 標籤選擇器數量 操作:滑鼠懸停在選擇器上,DevTools 會顯示權重計算。3. 查看計算樣式(Computed)用途:看到最終生效的值(經過繼承、覆蓋、預設值計算後) 使用時機:當 Styles 面板規則太多看不出問題時,直接看 Computed 找到最終值,再點擊展開追蹤來源。4. 即時修改測試用途:快速試錯,不用重新載入 實務流程:右鍵點擊元素 → 檢查在 Styles 面板點擊屬性值修改數值,瀏覽器立即套用確認效果後,回去改原始 CSS 檔案注意:DevTools 的修改是暫時的,重新整理會消失!5. 視覺化佈局工具Box Model 檢視器:查看元素實際的 margin、border、padding、contentFlexbox/Grid 檢視器:顯示 flex items 對齊狀況、grid cells 佈局偽類狀態切換:強制觸發 :hover、:focus、:active 等狀態重點整理Normal Flow 的三個層級Normal Flow(正常流):元素預設的排版系統 udn.realityrippleBlock Formatting Context:block 元素垂直堆疊的規則 udn.realityrippleInline Formatting Context:inline 元素水平並排的規則 udn.realityripple記憶口訣Block = 獨佔一行的框:可設定寬高,垂直堆疊Inline = 並排的文字流:不可設定寬高,水平排列Inline-Block = 並排的框:兼具兩者優點脫離 Normal Flow 的方法只要設定以下屬性,元素就會離開 normal flow: udn.realityrippleposition: absolute 或 fixedfloat: left 或 rightdisplay: flex 或 grid(子元素會進入新的排版上下文)延伸學習資源MDN - CSS SelectorsMDN - Specificity developer.mozillaMDN - Margin Collapsing developer.mozillaMDN - Normal Flow udn.realityrippleCSS Specificity Calculator cssbootcampThe Rules of Margin Collapse joshwcomeau筆記時間:2026-02-06 核心學習:CSS 選擇器語法、層疊順序、Normal Flow、Position、Margin Collapsing、HTML/CSS vs JavaScript 除錯差異 學習階段:Phase 2 - JavaScript 基礎 + CSS 切版
## Publication Information
- [雞蛋糕的前端修煉屋](https://paragraph.com/@gcake/): Publication homepage
- [All Posts](https://paragraph.com/@gcake/): More posts from this publication
- [RSS Feed](https://api.paragraph.com/blogs/rss/@gcake): Subscribe to updates