National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 80 24°C PM2.5 21
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 11

層疊、權重與繼承

兩條規則打架時誰贏:來源、權重、順序與繼承
Interaction 25 minute(s)

Learning Objectives

  • 說明同一個元素被多條規則選到、設定互相衝突時,瀏覽器比較的順序:來源與 !important、權重、出現順序
  • 算出選擇器的權重 (a, b, c),並逐欄比較誰比較高
  • 說明 style 屬性與 !important 為什麼會讓樣式難以維護,改用提高權重或調整順序解決
  • 分辨會繼承與不會繼承的屬性,用 inherit、initial 控制繼承
  • 在開發者工具裡看懂被劃掉的規則

兩條規則打架的時候

寫了一陣子 CSS 之後,你一定會遇到這種情況:明明寫了 .current { color: white; },連結卻還是灰色。 CSS 沒有報錯,因為它沒有錯:另一條規則也選中了這個連結,而且那一條比較「強」。

CSS 的 C 是 Cascading(層疊):同一個元素常常同時被好幾條規則選中,每條規則都想設定它的 color。 瀏覽器依一套固定的順序決定聽誰的,這套順序就叫層疊。另外,有些值沒有任何規則設定,元素會向父元素拿,這叫繼承(inheritance)。

搞懂這兩件事,你就不需要靠「多加幾個 !important 試試看」來修樣式。

層疊的比較順序

瀏覽器只比較「選中這個元素、而且設定同一個屬性」的宣告。比較的順序是:

順序 比什麼 說明
1 來源與重要性 瀏覽器預設樣式(user-agent stylesheet)最弱,你寫的作者樣式(author)比它強;加了 !important 的宣告勝過一般宣告
2 style 屬性 寫在標籤上的 style="…" 勝過樣式表裡的一般規則,不論權重多高
3 權重(specificity) 選擇器越「精準」越強,下一段細講
4 出現順序 以上都一樣時,寫在後面的勝出(後面的檔案、同一檔案裡比較下面的規則)

第 1 步的「瀏覽器預設樣式」就是標題變大、連結變藍、清單有縮排的來源。你寫的任何規則都比它強,所以只要寫 a { color: #52606d; } 就能蓋過連結的藍色。

還有使用者自訂樣式、動畫、@layer 圖層等來源,進階課程才會遇到;以上四步已經能解釋你平常遇到的絕大多數情況。

權重 (a, b, c) 怎麼算

把選擇器拆開,數三種東西:

欄 數什麼 例子
a id 選擇器 #signup
b class、屬性選擇器、虛擬類別 .btn、[target]、:hover、:nth-child(2)
c 元素選擇器、虛擬元素 a、li、::before

全域選擇器 * 和組合器(空白、>、+、~)不算。:is()、:not()、:has() 本身不算,算括號裡最高的那一個;:where() 一律是 0。

選擇器 權重
a (0, 0, 1)
.btn (0, 1, 0)
.event-card a (0, 1, 1)
a.btn.primary (0, 2, 1)
#signup (1, 0, 0)
#main-nav a:hover (1, 1, 1)

由左到右逐欄比:先比 a,a 大的直接勝出,後面不用看;a 一樣才比 b,再比 c。 所以 #signup(1, 0, 0)勝過 .a.b.c.d.e.f.g.h.i.j.k(0, 11, 0):欄和欄之間不會進位,11 個 class 也贏不了一個 id。

這也是上一課說「樣式用 class、不要用 id」的原因:id 的權重太高,之後想用 class 規則改它,只能寫出更長的選擇器或動用 !important。

權重實驗室

四條規則都想設定「立即報名」按鈕的文字顏色。每條規則下面標出它的權重、有沒有選到按鈕、是勝出還是被覆蓋(劃掉)。你可以勾選停用規則、直接改選擇器、切換 !important、用 ↑↓ 調整順序;右邊是瀏覽器真的算出來的顏色。

style 屬性與 !important

style 屬性直接寫在標籤上,勝過樣式表裡的任何一般規則。想用 CSS 改它,只剩 !important 一條路,這就是第 9 課建議把樣式搬進 CSS 的原因。

!important 加在值的後面,讓這條宣告跳過權重比較:

.current { color: #ffffff !important; }

它看起來很方便,但會讓樣式越來越難改:

  • 下次要蓋過它,只能再寫一個權重更高的 !important,整份 CSS 開始比誰的 !important 多。
  • 讀程式的人看不出真正的原因:是選擇器寫錯?順序不對?還是被別的規則蓋掉?

遇到樣式被蓋掉時,先依層疊順序找原因,再用正常的方法解決:

原因 解法
對方的權重比較高 讓你的選擇器多一個 class(.nav .current),或把對方的 id 選擇器改成 class
權重一樣但你寫在前面 把規則移到後面
被 style 屬性蓋掉 刪掉 HTML 上的 style 屬性

!important 只留給少數真正需要的地方,例如覆蓋你改不到的第三方樣式;用的時候加註解說明原因。

互動練習:不用 !important 修好導覽列

「活動」是目前所在的頁面,應該是藍底白字,卻變成藍底灰字;「聯絡我們」也莫名其妙變成橘色。找出原因,不使用 !important 修好它們。

小測驗:層疊與權重

1.

#nav .item a 的權重是多少?

2.

一條規則用了 11 個 class 選中按鈕(0, 11, 0),另一條用 #signup(1, 0, 0)。都設定 color,誰勝出?

3.

樣式表裡先寫 .btn { color: red; },後面再寫 .btn { color: blue; },按鈕是什麼顏色?

4.

<p id="intro" style="color: green;">,樣式表裡有 #intro { color: red; }。段落是什麼顏色?

第 1 次作答

繼承:沒設定的值向父元素拿

在 <article> 設定 color 和 font-family,裡面的標題、段落都會跟著變,不用一個一個寫,這是繼承。 但 border 不會:article 有框線,裡面的每個段落並不會各自多一圈框線。

通常會繼承(和文字有關) 通常不會繼承(和盒子有關)
color、font-family、font-size、font-weight、line-height margin、padding、border
text-align、letter-spacing、list-style、visibility background-color、width、height、display

每個屬性會不會繼承,MDN 的屬性頁面都有寫(「Inherited: yes/no」)。

繼承的值最弱:只要有任何規則直接選中這個元素,即使只是瀏覽器預設樣式,都會蓋過繼承來的值。 所以文章的 color 傳不到 <a>(瀏覽器預設讓連結變藍),字型也傳不到 <button>(瀏覽器預設給按鈕自己的字型)。

用關鍵字可以手動控制:

關鍵字 意思
inherit 用父元素的值(不會繼承的屬性也能強制繼承)
initial 用這個屬性在規格裡的初始值(例如 color 的初始值通常是黑色)
unset 會繼承的屬性當成 inherit,不會繼承的當成 initial
button, input, select { font: inherit; }   /* 表單元件跟著頁面的字型,常見的重設寫法 */
.post a { color: inherit; }                /* 連結跟著文章的顏色,再用底線區分 */

互動練習:繼承、inherit 與 initial

.post 設定了顏色、字型和框線。按「執行」先觀察:哪些元素跟著變了、哪些沒有?然後依任務修改 CSS。

在開發者工具裡看層疊

在網頁上按右鍵選「檢查」(或按 F12),選一個元素,右側的「樣式」(Styles)面板就是這一課的內容:

  • 所有選中這個元素的規則,由強到弱從上往下列出;最上面是 element.style,也就是 style 屬性。
  • 被更強的規則蓋掉的宣告會被劃掉,就像權重實驗室裡的灰色規則。
  • 往下捲會看到「繼承自 article」這種分組,列出從祖先繼承來的屬性;最下面通常是 user agent stylesheet,也就是瀏覽器預設樣式。
  • 「計算後」(Computed)分頁列出每個屬性最後的值,點開可以看到是哪一條規則決定的。
  • 滑鼠移到選擇器上,會顯示它的權重(Specificity)。

樣式沒有照預期出現時:先選中那個元素,看你的宣告是沒出現(選擇器沒選中、或語法錯了)還是被劃掉(被更強的規則蓋掉),再依層疊順序找原因。

小測驗:繼承與 !important

1.

在 <section> 設定下面哪一個屬性,裡面的段落會跟著繼承?

2.

為什麼不建議用 !important 解決「樣式被蓋掉」?

3.

body { font-family: "Noto Sans TC", sans-serif; },但頁面上的按鈕仍是另一種字型。最常見的修法是?

第 1 次作答

重點整理

  • 只有「選中同一個元素、設定同一個屬性」的宣告才會互相比較。
  • 比較順序:來源與 !important → style 屬性 → 權重 → 出現順序(後面的勝出)。你寫的樣式勝過瀏覽器預設樣式。
  • 權重 (a, b, c):a 數 id,b 數 class/屬性/虛擬類別,c 數元素/虛擬元素;由左到右逐欄比,不會進位。
  • 樣式被蓋掉時先找原因,用提高權重、調整順序、刪掉 style 屬性解決,不要用 !important 硬壓。
  • 文字類屬性會繼承、盒子類屬性不會;繼承的值最弱;用 inherit、initial、unset 手動控制。
  • 開發者工具的「樣式」面板由強到弱列出規則,被蓋掉的宣告會劃掉。

下一課講文字與字型:字型堆疊、自己提供字型檔、行高,以及中文排版的習慣。

這一課完成了!
Next lesson:文字與字型
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。