網頁功能:
容器樣式查詢
問題
我們通常需要結合不同類型的篩選條件,例如選取器 + 媒體查詢、媒體查詢 + 容器查詢等。
舉例來說,將 (prefers-color-scheme: dark) 與指定色彩配置覆寫值的選取器 (例如 :root:has(> head > meta[name="color-scheme"][content="dark"]) 或 :root.dark) 結合,無論色彩配置設定為何,都能在淺色/深色模式下套用特定樣式。
簡單的做法會導致程式碼重複:
/* Light mode styles */
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
@media (prefers-color-scheme: dark) {
/* Dark mode styles */
:root:not(.light) {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
}
/* Dark mode styles, again */
:root.dark {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
建議做法
將合併篩選器的結果儲存在自訂屬性中,然後使用容器樣式查詢,根據該屬性設定規則。
重要事項:由於容器查詢的運作方式,只有在我們能為必須比對的任何規則設定上層自訂屬性時,這項技術才有效。
1. 將選取邏輯與套用規則分開
:root {
--color-scheme: light;
@media (prefers-color-scheme: dark) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="dark"]) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="light"]) {
--color-scheme: light;
}
}
2. 套用規則的自訂屬性鍵
@container not style(--color-scheme: dark) {
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
}
@container style(--color-scheme: dark) {
.card.featured {
font-weight: 300;
}
#logo {
display: none;
}
}
3. 選用:切換顯示設定的公用程式類別
常見的做法是根據條件是否相符,切換顯示設定。公用程式類別必須優先於任意元件樣式 (因此 !important),且其顯示的 display 未知,因此無法使用覆寫,請使用 not style(...) 進行閘道:
@container not style(--color-scheme: dark) {
.if-dark {
display: none !important;
}
}
@container not style(--color-scheme: light) {
.if-light {
display: none !important;
}
}
備用廣告
備用方案分為兩種類型,取決於分支的重要性,以及可接受的備用方案。
- 對於關鍵分支,即使不支援樣式查詢,所有狀態也必須正常運作,因此您無法使用樣式查詢。請改用上述基本方法,為每個狀態複製規則。只要公用程式類別也以這種方式定義,就仍可使用。
- 對於非關鍵分支,如果可接受預設狀態,您可以在任何
@container規則之外定義基本樣式,並僅使用樣式查詢做為覆寫。這種做法保留了大部分的精神,主要缺點是覆寫會導致值耦合。
#logo-dark {
display: none;
}
@container style(--color-scheme: dark) {
#logo-dark {
display: inline; /* override */
}
#logo {
display: none;
}
}