LESSON-04 · 自主延伸

選擇器、繼承與無效宣告

把「選擇器、繼承與無效宣告」拆成 4 個可獨立完成、可重設、可驗證的自主學習 module。

1. 現在要做什麼

成果:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

需要的檔案:files/starter/index.html(整合起點,保留跨 module 的最小缺口。)

完成後:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

0 / 8 個操作已記錄

2. 先備自我檢查

逐項展開;答不出來時先走補救連結,不必硬做。

已完成本章基礎練習並能找到 Starter。

自我檢查:我能否指出本章 Starter 入口與唯一 TODO?

不足時補救:回到本章 README,先完成基礎練習與入口導覽。

能開啟本機 HTML 並讀取至少一種瀏覽器證據。

自我檢查:我能否開啟 Elements、Console 或 Network 並找到本頁?

不足時補救:先開 DevTools,重新整理一次,確認目前文件與第一筆 request。

3. 完整學習目標與 Learning Map

每一個目標只對應一個 module;成功狀態必須能指出證據。

能用 Computed 判斷文字 color 會由父層傳給子層,而 border-width 預設不會。

為什麼重要
若把所有屬性都當成會繼承,常會在子元素重複補樣式,或誤判邊框沒有出現是 selector 失效。
完成條件
不查看 Solution,先讀父層 color/border,再檢查子層的 color 與 border-top-width。
成功狀態
子層 color 與父層相同;border-top-width 初始為 0px,加入明確 inherit 後才成為 4px。
證據位置
實驗 before=0px、after=4px;同一子層的 Computed color 與父層相同

能用空白 combinator 命中任意深度後代,並用 > 只命中直接子元素。

為什麼重要
選錯 combinator 會讓規則滲入元件深層,或讓巢狀內容意外漏掉樣式。
完成條件
同一卡片保留一個直接 p 與一個包在 div 裡的 p,分別觀察兩條 selector。
成功狀態
直接 p 同時得到 color 與 font-weight;巢狀 p 只得到 descendant color,不得到 child font-weight。
證據位置
巢狀 p 的 computed color 由 rgb(23, 50, 77) 變 rgb(21, 94, 117),font-weight 仍維持 400

能用逗號組成 selector list,讓 h2 與 h3 共用同一組宣告。

為什麼重要
合併真正相同的宣告能減少重複;但其中一個 selector 無效時,傳統 selector list 的整組規則可能失效。
完成條件
在同一 fixture 中放入 h2、h3 與普通 p,只計算 selector list 真正匹配的元素。
成功狀態
h2.selector-list-hit 與 h3.selector-list-hit 共匹配 2 個唯一元素;p 不在集合內。
證據位置
count=2、uniqueCount=2、valid=true,輸出文字同時包含章節標題與卡片標題

能證明無效 color 宣告會被忽略,前一個有效 computed color 仍保留。

為什麼重要
CSS 通常不因單一錯誤讓整頁停止;若不知道容錯規則,容易誤以為整份 CSS 沒載入。
完成條件
先取得有效 color,再切換一個只含無效 color 值的 class。
成功狀態
before 與 after 都是 rgb(23, 50, 77),Styles 可指出無效 `color: definitely-not-a-color`。
證據位置
runtime before 與 after 都等於 rgb(23, 50, 77),property=color

4. 4 個知識模組與 Micro Labs

依序展開;每次只改一項,操作後確認該模組自己的 DOM、progress 與 evidence。

1繼承與非繼承屬性

完整解釋

白話:文字顏色像家族特徵,子層通常會沿用;邊框像各自的外框,不會自動傳下去。

正式說法:CSS property 具有不同的 inherited initial definition;color 預設繼承,border-width longhands 預設不繼承。

何時使用:子元素沒有自行宣告,但 Computed 值仍受祖先影響,或父層有邊框而子層沒有時。

修改前後:Before:看到父層 color 與 border 就預期子層兩者都有。After:先查 property 是否 inherited,再用子層 Computed 證明。

常見混淆:繼承不是 cascade 勝負;cascade 先決定元素自己的指定值,繼承是在缺少適用宣告時取得父層值。

名詞與最小範例

繼承與非繼承屬性 Inherited and non-inherited properties

白話
文字顏色像家族特徵,子層通常會沿用;邊框像各自的外框,不會自動傳下去。
正式定義
CSS property 具有不同的 inherited initial definition;color 預設繼承,border-width longhands 預設不繼承。
何時使用
子元素沒有自行宣告,但 Computed 值仍受祖先影響,或父層有邊框而子層沒有時。
最小範例
.parent { color: #17324d; border: 4px solid; } .child { border-width: inherit; }
驗收證據
實驗 before=0px、after=4px;同一子層的 Computed color 與父層相同
常混淆
繼承不是 cascade 勝負;cascade 先決定元素自己的指定值,繼承是在缺少適用宣告時取得父層值。

Micro Lab|繼承與非繼承屬性

情境:服務卡父層已有品牌文字色與外框,但卡片內的說明文字只有顏色相同、沒有自己的邊框。

起始狀態:父層 color 為 rgb(23, 50, 77)、border 為 4px;子層沒有 border-width 宣告。

  1. 執行實驗先讀子層 border-top-width,再切換 .inherit-border 令 border-width 明確使用 inherit。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:繼承與非繼承屬性

父層子層文字
尚未執行;DOM data-state=starter。

預期:子層 color 與父層相同;border-top-width 初始為 0px,加入明確 inherit 後才成為 4px。

證據:實驗 before=0px、after=4px;同一子層的 Computed color 與父層相同

第一個檢查:在 Elements 選取 data-inheritance-child,先讀 Computed color 與 border-top-width。

重設:重新載入 module,讓子層移除 inherit-border class。

卡住時

  • 症狀:子層一開始就有 4px 邊框。
    可能原因:fixture 的 selector 直接命中子層,或子層初始 class 已含 inherit-border。
    先檢查:查看子層 class 與 Styles 中 border-width 的來源。
    修正:移除子層初始 border 宣告,只保留父層 border 與切換後規則。

理解檢查

哪組結果正確描述預設繼承?

尚未作答。

查看解釋

color 的 property definition 為 inherited;border width longhands 則不是。

本模組官方來源:MDN|Inheritance

2後代與子代 combinator

完整解釋

白話:空白是『裡面不管隔幾層』;> 是『下一層就是它』。

正式說法:Descendant combinator 匹配某祖先內的後代元素;child combinator 僅匹配指定父元素的直接子元素。

何時使用:要限制元件第一層結構,或要讓深層內容也沿用特定規則時。

修改前後:Before:.card p 與 .card > p 被當成相同。After:能從 DOM 深度預測每個 selector 的匹配集合。

常見混淆:.card > p 不是選取所有 card 內的 p;中間多一層 div 就不匹配。

名詞與最小範例

後代與子代 combinator Descendant and child combinators

白話
空白是『裡面不管隔幾層』;> 是『下一層就是它』。
正式定義
Descendant combinator 匹配某祖先內的後代元素;child combinator 僅匹配指定父元素的直接子元素。
何時使用
要限制元件第一層結構,或要讓深層內容也沿用特定規則時。
最小範例
.card p { color:#155e75 } .card > p { font-weight:700 }
驗收證據
巢狀 p 的 computed color 由 rgb(23, 50, 77) 變 rgb(21, 94, 117),font-weight 仍維持 400
常混淆
.card > p 不是選取所有 card 內的 p;中間多一層 div 就不匹配。

Micro Lab|後代與子代 combinator

情境:卡片的第一層摘要要粗體,但深層補充文字只需要品牌色。

起始狀態:一個 p 是 card 直接子層,另一個 p 位於 card > div > p。

  1. 執行實驗在巢狀 p 切換 probe-on;descendant 規則命中 color,但 child 規則因非直接子層不命中。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:後代與子代 combinator

直接子層

巢狀後代

尚未執行;DOM data-state=starter。

預期:直接 p 同時得到 color 與 font-weight;巢狀 p 只得到 descendant color,不得到 child font-weight。

證據:巢狀 p 的 computed color 由 rgb(23, 50, 77) 變 rgb(21, 94, 117),font-weight 仍維持 400

第一個檢查:先在 Elements 沿父層往上數,確認被測 p 與 .card 中間有一個 div。

重設:重新載入 module,移除巢狀 p 的 probe-on class。

卡住時

  • 症狀:巢狀 p 也變成粗體。
    可能原因:font-weight 規則寫成 .card p,或 p 被移到 card 直接子層。
    先檢查:在 Elements 確認 DOM 深度,並查看 Styles 中 font-weight 的 selector。
    修正:把粗體 selector 限定為 .card > p,保留 div 包住巢狀 p。

理解檢查

哪個 selector 只命中 .card 的直接 p 子層?

尚未作答。

查看解釋

> 是 child combinator,只允許一層父子關係。

本模組官方來源:MDN|CSS selectors and combinators

3selector list

完整解釋

白話:逗號像『以及』:這組樣式給 h2,也給 h3。

正式說法:Selector list 是以 comma 分隔的 selector 序列;規則宣告套用到清單中任一 selector 匹配的元素。

何時使用:多種元素或 class 確實需要完全相同的一組宣告時。

修改前後:Before:h2、h3 各複製一份相同規則。After:用一條 selector list 管理共同責任。

常見混淆:逗號不是後代關係;h2 h3 表示 h2 裡的 h3,h2, h3 才是兩個獨立 selector。

名詞與最小範例

selector list Selector list

白話
逗號像『以及』:這組樣式給 h2,也給 h3。
正式定義
Selector list 是以 comma 分隔的 selector 序列;規則宣告套用到清單中任一 selector 匹配的元素。
何時使用
多種元素或 class 確實需要完全相同的一組宣告時。
最小範例
h2, h3 { color:#155e75; }
驗收證據
count=2、uniqueCount=2、valid=true,輸出文字同時包含章節標題與卡片標題
常混淆
逗號不是後代關係;h2 h3 表示 h2 裡的 h3,h2, h3 才是兩個獨立 selector。

Micro Lab|selector list

情境:首頁的區塊標題與卡片標題要共用品牌色,但普通段落不應被選入。

起始狀態:fixture 含一個 h2、一個 h3 與一個 p;只有前兩者具有 selector-list-hit。

  1. 執行 collection probe,以 h2.selector-list-hit, h3.selector-list-hit 查找共同匹配集合。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:selector list

服務內容

居家清潔

普通說明

尚未檢查
尚未執行;DOM data-state=starter。

預期:h2.selector-list-hit 與 h3.selector-list-hit 共匹配 2 個唯一元素;p 不在集合內。

證據:count=2、uniqueCount=2、valid=true,輸出文字同時包含章節標題與卡片標題

第一個檢查:在 Elements 數出 h2.selector-list-hit 與 h3.selector-list-hit,確認 p 沒有該 class。

重設:重新載入 module;集合由固定本機 DOM 重新建立。

卡住時

  • 症狀:集合數量是 0 或包含普通 p。
    可能原因:漏掉逗號、class 拼錯,或把 p 也加入 selector list。
    先檢查:把 itemSelector 拆成逗號左右兩段,分別在 Console 執行 querySelectorAll。
    修正:使用 h2.selector-list-hit, h3.selector-list-hit,移除 p selector。

理解檢查

`h2, h3` 代表什麼?

尚未作答。

查看解釋

逗號分隔 selector list;空白與 > 才是關係 combinator。

本模組官方來源:MDN|Selector list

4瀏覽器如何忽略無效宣告

完整解釋

白話:瀏覽器看到不認得的屬性值,會跳過那一筆,繼續使用其他有效規則。

正式說法:當 declaration 的 property value 不符合該 property grammar,user agent 會忽略該 declaration,不會回溯改寫其他有效 declarations。

何時使用:某一個 CSS property 沒生效,但同一規則或同一檔案的其他樣式仍正常時。

修改前後:Before:看到一行錯誤就認為整份 stylesheet 壞掉。After:在 Styles 找無效宣告,再讀 Computed 的實際保留值。

常見混淆:被 cascade 覆蓋的有效宣告與語法無效的宣告不同;前者可解析但輸掉,後者不會成為指定值。

名詞與最小範例

瀏覽器如何忽略無效宣告 CSS error handling for invalid declarations

白話
瀏覽器看到不認得的屬性值,會跳過那一筆,繼續使用其他有效規則。
正式定義
當 declaration 的 property value 不符合該 property grammar,user agent 會忽略該 declaration,不會回溯改寫其他有效 declarations。
何時使用
某一個 CSS property 沒生效,但同一規則或同一檔案的其他樣式仍正常時。
最小範例
.copy { color:#17324d } .copy.invalid-value { color:definitely-not-a-color }
驗收證據
runtime before 與 after 都等於 rgb(23, 50, 77),property=color
常混淆
被 cascade 覆蓋的有效宣告與語法無效的宣告不同;前者可解析但輸掉,後者不會成為指定值。

Micro Lab|瀏覽器如何忽略無效宣告

情境:同事把品牌文字色寫成不存在的 CSS 顏色名稱,但頁面仍顯示前一條有效顏色。

起始狀態:目標元素由基礎規則取得 rgb(23, 50, 77),尚未加 invalid-value class。

  1. 執行實驗切換 invalid-value class,前後都讀取同一元素的 computed color。
  2. 執行下方操作,觀察獨立的 DOM 與資料狀態。
  3. 依證據欄位重新驗收。

目前主題:瀏覽器如何忽略無效宣告

品牌說明文字

尚未執行;DOM data-state=starter。

預期:before 與 after 都是 rgb(23, 50, 77),Styles 可指出無效 `color: definitely-not-a-color`。

證據:runtime before 與 after 都等於 rgb(23, 50, 77),property=color

第一個檢查:先在 Computed 記下 color,再到 Styles 找 color 值旁的無效提示。

重設:重新載入 module,移除 invalid-value class。

卡住時

  • 症狀:切換後 computed color 真的改變。
    可能原因:所用值其實是合法 CSS color,或另一條有效規則同時命中。
    先檢查:在 Styles 檢查 invalid-value 規則的原始值與其他 color 宣告。
    修正:fixture 只保留一條基礎有效值與一條明確無效值 definitely-not-a-color。

理解檢查

無效 color 宣告通常會造成什麼結果?

尚未作答。

查看解釋

CSS error handling 會盡量繼續解析,無效 declaration 不會覆蓋有效值。

本模組官方來源:MDN|CSS error handling

5. 選擇器、繼承與無效宣告|整合 Lab

情境:在同一份章節作品中整合 4 個 module,排除單項通過但組合失敗的問題。

交付:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

尚未執行整合步驟。
  1. 1觀察整合 Starter 並找出第一個未通過 module。

    檔案:files/starter/index.html 定位:#observe

    操作:逐項讀取 outcomes,執行一次現況操作。

    // OBSERVE:不修改程式,先記錄第一個失敗 moduleId。

    預期:能指出第一個未通過 module。

    證據:第一個 moduleId 與缺少的 evidence。

    原因:先觀察可避免未重現就直接改答案。

    卡住先查:確認開啟的是 files/starter/index.html。

  2. 2依 module 順序修改,一次只加入一個責任。

    檔案:files/starter/index.html 定位:#modify

    操作:執行實驗先讀子層 border-top-width,再切換 .inherit-border 令 border-width 明確使用 inherit。 → 執行實驗在巢狀 p 切換 probe-on;descendant 規則命中 color,但 child 規則因非直接子層不命中。 → 執行 collection probe,以 h2.selector-list-hit, h3.selector-list-hit 查找共同匹配集合。 → 執行實驗切換 invalid-value class,前後都讀取同一元素的 computed color。

    // 04-01-topic: 執行實驗先讀子層 border-top-width,再切換 .inherit-border 令 border-width 明確使用 inherit。
    // 04-02-combinator: 執行實驗在巢狀 p 切換 probe-on;descendant 規則命中 color,但 child 規則因非直接子層不命中。
    // 04-03-selector-list: 執行 collection probe,以 h2.selector-list-hit, h3.selector-list-hit 查找共同匹配集合。
    // 04-04-topic: 執行實驗切換 invalid-value class,前後都讀取同一元素的 computed color。

    預期:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

    證據:實驗 before=0px、after=4px;同一子層的 Computed color 與父層相同;巢狀 p 的 computed color 由 rgb(23, 50, 77) 變 rgb(21, 94, 117),font-weight 仍維持 400;count=2、uniqueCount=2、valid=true,輸出文字同時包含章節標題與卡片標題;runtime before 與 after 都等於 rgb(23, 50, 77),property=color

    原因:逐項整合能把回歸定位到明確 module。

    卡住先查:回到第一個未通過的 module,只修該處。

  3. 3驗證所有 module 在整合後仍成立。

    檔案:files/solution/index.html 定位:#verify

    操作:重新整理並依 outcomes 順序重跑所有證據。

    // VERIFY:逐項記錄 pass/fail,不以看到畫面代替 evidence。

    預期:4/4 module 通過。

    證據:每個 moduleId 都有實際結果與重設後重現紀錄。

    原因:單項通過不代表整合後沒有 selector、id 或狀態衝突。

    卡住先查:若失敗,回到第一個失敗 module,不同時修多項。

  4. 4把本章責任轉用到不同內容情境。

    檔案:files/starter/index.html 定位:#challenge

    操作:替另一個商家情境重做,仍達成:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

    // CHALLENGE:只替換內容與資料,不新增框架或跳過 self-check。

    預期:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

    證據:轉用後的作品與全數 module self-check。

    原因:能轉用才代表理解責任,而非只記住原範例。

    卡住先查:先確認共同基底與 module id 未被改壞。

重設方法:重新載入 files/starter/index.html;若 localStorage 不可用,使用頁面內記憶狀態並提供重設按鈕。

6. 自學挑戰與三層提示

挑戰:將同一組責任轉用到另一個商家情境,仍達成:完成一張能解釋 selector 命中、繼承與 cascade 結果的服務卡。

限制:不新增框架。;保留 module id 與驗收證據。

提交證據:提交可直接開啟的作品與逐項 self-check。

提示 1|方向提示

拆小:在「選擇器、繼承與無效宣告」先完成第一個尚未通過的 module:繼承與非繼承屬性,不同時修改其他責任。

提示 2|關鍵片段

串接:依 04-01-topic → 04-02-combinator → 04-03-selector-list → 04-04-topic 核對各自輸入與證據。

提示 3|完整解答與原因

完整解答與原因:依序執行 執行實驗先讀子層 border-top-width,再切換 .inherit-border 令 border-width 明確使用 inherit。 → 執行實驗在巢狀 p 切換 probe-on;descendant 規則命中 color,但 child 規則因非直接子層不命中。 → 執行 collection probe,以 h2.selector-list-hit, h3.selector-list-hit 查找共同匹配集合。 → 執行實驗切換 invalid-value class,前後都讀取同一元素的 computed color。;這個順序能把每個結果對回單一 module,避免整合後無法定位。

完整解答預設收合;先留下自己的嘗試,再開第三層。

7. 症狀式除錯指南

8. 理解測驗、驗收證據與下一步

哪個狀態代表 04-01-topic 完成?

尚未作答。

查看解釋

若把所有屬性都當成會繼承,常會在子元素重複補樣式,或誤判邊框沒有出現是 selector 失效。

哪個狀態代表 04-02-combinator 完成?

尚未作答。

查看解釋

選錯 combinator 會讓規則滲入元件深層,或讓巢狀內容意外漏掉樣式。

哪個狀態代表 04-03-selector-list 完成?

尚未作答。

查看解釋

合併真正相同的宣告能減少重複;但其中一個 selector 無效時,傳統 selector list 的整組規則可能失效。

哪個狀態代表 04-04-topic 完成?

尚未作答。

查看解釋

CSS 通常不因單一錯誤讓整頁停止;若不知道容錯規則,容易誤以為整份 CSS 沒載入。

驗收清單

官方來源

回到課程地圖選擇下一章