模板原本的卡片標題是藍色,你在後面加上紅色規則,畫面卻還是藍色。先別急著補!important:後寫的規則不一定會贏,選擇器的權重也會影響結果。若你正在製作可被不同頁面調整的基礎樣式,:where()能讓這層規則更容易覆寫。
:where()可以把多個選擇器放在同一組,也可以包含較完整的選取條件。它特別的地方是自身及括號內的選擇器不增加specificity。範圍仍然照樣匹配,但不用把那段範圍的權重帶到每次覆寫裡。
先重現後寫也蓋不掉的情況
以下HTML是一張放在theme容器裡的卡片。CSS先設定基礎藍色,再設定頁面想用的紅色。兩條規則都命中同一個元素,卻不是只看哪條寫在最後。
<div class="theme">
<article class="card">商務模板</article>
</div>
.theme .card {
color: #2454a4;
}
.card {
color: #b3261e;
}
在本例相同來源、相同重要性、沒有cascade layer等額外條件下,兩個class的.theme .card權重高於只有一個class的.card,因此顏色仍是藍色。將這兩條規則前後交換,也不會讓.card突然贏過較高權重的規則。
如果這是你自己維護的基礎樣式,可以把整段選取條件放進:where()。匹配的仍是theme裡的card,權重卻變成零,後面的.card就能設定紅色。
:where(.theme .card) {
color: #2454a4;
}
.card {
color: #b3261e;
}
這不是取消基礎樣式,也不是讓所有元素變成低權重。只有放在:where括號裡的那段選擇器不增加權重;它仍有原本的匹配範圍。沒有被後面規則覆寫的屬性,仍會使用基礎設定。
放在哪一段,保留下來的權重就不同
你可以只把外層範圍放進:where,保留元件class的權重。這通常比把每個規則都降到零更容易維持元件邊界。
:where(.theme) .card {
color: #2454a4;
}
.card {
color: #b3261e;
}
這次:where(.theme)不加權重,外面的.card仍是一個class。兩條規則權重相同,在本例其他cascade條件相同時,後面的.card勝出。若你把頁面覆寫規則移到前面,則後面的基礎規則可能再把它蓋回去。因此「整段歸零」與「只讓範圍歸零」有不同用途,應按樣式架構選擇。
也別把:where與:is當成完全相同的工具。兩者都能接受選擇器清單,但:is會採用參數中最高的specificity。若:is(.card, #featured)命中card,裡面那個ID會讓整個:is帶上ID等級的權重;換成:where則不會。你只是想整理重複選擇器時,也要留意是否意外加入高權重條件。
它適合基礎層,不是所有覆寫問題的萬用解法
可重用的模板元件常需要一層預設顏色、間距與字型,再讓頁面或客戶樣式調整。這些預設規則可以採較低權重,讓覆寫不用一直增加外層class或ID。像:where(.template-page) h2,就能把頁面範圍留住,同時避免範圍本身抬高權重。
反過來,真正代表元件狀態的規則,例如欄位錯誤、按鈕停用或展開狀態,是否要降到零就需要評估。若狀態樣式很容易被普通顏色規則蓋掉,使用者可能看不出錯誤或停用。不要整份搜尋取代所有選擇器,先從清楚的基礎預設開始,逐項確認狀態與互動。
第三方CSS若含!important,單純把自己的規則放進:where不會幫你勝出;那反而降低了你的權重。行內樣式、樣式來源、cascade layer、重要性與動畫等,也可能先於普通specificity比較影響結果。要調整第三方主題,先確認輸掉的是哪個cascade階段,而不是只數class有幾個。
從Computed與Styles面板找真正勝出的宣告
本機Chromium案例比較了三種基礎選擇器:.theme .card得到藍色,:where(.theme .card)得到紅色,:where(.theme) .card在後面的.card規則下也得到紅色。案例只針對同來源普通規則;其他主題的!important與layer設定,仍要對照實際cascade。
自己的頁面可以選取元素,先在Computed查看最後的color,再到Styles確認哪條宣告被劃掉,以及規則來自哪個檔案。若你新加的規則根本沒有出現,可能是CSS未載入、selector沒命中或語法錯誤,這些問題不能靠:where修好。先確認規則存在且命中,再談權重。
檢查時一次只改一個選擇器,不要同時調整載入順序、layer和important。修好後再確認其他同元件的頁面,以及hover、focus、錯誤與停用狀態。基礎規則更容易覆寫是一種設計選擇,變更也可能讓原本被壓住的規則開始生效,需要看到實際結果才能判斷。
把可覆寫的範圍寫清楚
處理響應式規則時,也要注意相同元素在不同寬度下命中的規則。假設桌面卡片用低權重基礎色,窄螢幕又有一條.theme .card指定顏色,那個media query成立時仍可能蓋過頁面的.card。media query並不自行增加specificity,但它決定規則是否參與比較;只在桌面確認紅色生效,不能直接推論手機也相同。
另一個常見誤會是繼承。你在外層容器設定color,子卡片本身已有命中的color宣告時,子卡片會使用自己的值,不能只比較外層選擇器有多長。排查時先看宣告究竟在同一個元素上競爭,還是從父層繼承過來。本文的三個案例都在同一張卡片上設定color,所以可以直接比較選擇器;改成父子不同元素時,分析方式也要跟著調整。
如果你無法修改主題的基礎規則,先以自己的小元件確認:where行為,再決定是否需要在可控制的樣式層處理覆寫。不要把教學範例直接取代正式主題的整份檔案;保留既有載入與狀態規則,逐個屬性核實哪一條宣告需要變更,才不會修顏色卻弄壞其他頁面。
例如你希望文章頁的卡片顏色可以調整,但後台管理卡片維持原樣,保留明確的容器條件會比把.card套到全站更穩定。:where不會替你建立隔離邊界,括號內的範圍仍應正確。不要為了零權重而省掉必要的頁面條件,否則規則可能命中本來無關的元件。
若團隊使用cascade layers,可以另外規劃基礎、元件和頁面覆寫的順序;那是另一層cascade設計,與:where的specificity用途互相配合。先讓每一層的責任清楚,避免基礎規則到處用!important、頁面又不斷加ID追上去。本文的小案例可以幫你看懂權重變化,套到完整專案前仍要對照實際layer與來源。
維護時可以在元件文件註明哪些屬性預期讓頁面覆寫、哪些狀態由元件控制。這樣新同事看到:where就知道它在降低基礎設定的成本,而不會為了「看起來比較新」把所有選擇器都換掉。用可重現的元素與計算樣式確認效果,會比反覆加更長選擇器更容易找出原因。

評論0