背景與總覽
作者通常需要根據情境變更元件設計。過去,作者必須使用選取器才能套用這類變更。這通常意味著,雖然許多設計權杖可以做為自訂屬性存在,但高階設計權杖只能編碼為選取器模式 (即使用類別名稱或屬性慣例),或 JavaScript 架構中的屬性/內容。
容器樣式查詢可讓作者根據祖系元素的計算自訂屬性值,設定元素樣式。這表示作者可以在樣式表中編寫有意義的設計權杖值,而不必依賴標記或 JavaScript 進行呈現。
導入方式
使用容器樣式查詢實作反應式設計權杖相當簡單:
- 將高階設計權杖設為容器的自訂屬性。這不需要是已註冊的自訂屬性。
- 使用
@container style()規則查詢該自訂屬性的值。 - 將適當的樣式套用至容器內的子系元素。
注意事項:
- 使用樣式查詢進行查詢的容器不需要設定
container-type或container-name,但container-name可讓查詢更具體。 - 容器本身無法透過容器樣式查詢設定樣式。
以下是上述實作步驟的基本範例。
<div class="features">
<div class="card"></div>
<div class="card"></div>
</div>
<div class="bugs">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
.features {
--density: spacious;
}
.bugs {
--density: compact;
}
@container style(--density: compact) {
.card {
padding: 8px;
}
}
@container style(--density: spacious) {
.card {
padding: 24px;
}
}
備用策略
在基準支援容器樣式查詢之前,我們「不建議」將其用於必須在所有瀏覽器中提供的核心功能,因為要為其建立備用方案並不容易,而且不會影響其優點或有其限制。舉例來說,如果 UI 密度使用者偏好設定不屬於所有體驗都必須提供的核心功能,則可使用容器樣式查詢來實作該功能,而不必使用備用方案。
改用選取器
如果是核心功能,請改用選取器。這個範例使用 data-density 屬性,在標記中編碼密度設計權杖,而不是做為自訂屬性:
<div class="features" data-density="spacious">
<div class="card"></div>
<div class="card"></div>
</div>
<div class="bugs" data-density="compact">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
/* This example uses `:where()` to avoid increasing specificity */
:where([data-density="compact"]) .card {
padding: var(--card-padding-compact);
}
:where([data-density="spacious"]) .card {
padding: var(--card-padding-spacious);
}
這個備用方法的重大限制是,不支援使用 data-density 屬性集巢狀元素,因為選取器特異性相同,系統會使用顯示順序來決定樣式 (即 [data-density="spacious"] 一律優先於 [data-density="compact"])。
使用樣式查詢做為漸進增強
雖然我們不建議這麼做,但如果您想使用樣式查詢做為核心功能的漸進增強,可以建立一些自訂屬性,然後在後面加入樣式查詢,避免重複。選取容器元素時,請務必使用 :where() 做為備用方法,以免提高特異性。
.card {
--card-padding-compact: 8px;
--card-padding-spacious: 24px;
}
:where([data-density="compact"]) .card {
padding: var(--card-padding-compact);
}
:where([data-density="spacious"]) .card {
padding: var(--card-padding-spacious);
}
/* Use style queries as a progressive enhancement: same specificity, so order of appearance is used */
@container style(--density: compact) {
.card {
padding: var(--card-padding-compact);
}
}
@container style(--density: spacious) {
.card {
padding: var(--card-padding-spacious);
}
}
僅使用 CSS 檢查功能
如要檢查容器樣式查詢功能,並根據條件顯示依賴該功能的 UI,可以使用樣式查詢:
:root {
--style-queries-supported: check;
}
.density-toggle {
display: none;
}
@container style(--style-queries-supported) {
.density-toggle {
display: revert;
}
}
使用 JavaScript 檢查功能
使用 JavaScript 檢查功能時,情況會稍微複雜一些,因為 CSSContainerRule 介面在新增容器樣式查詢之前就已存在,因此不適合用於這項用途。您必須改為檢查使用樣式查詢設定的已知屬性計算值。
這個範例使用自訂屬性,因為不會產生視覺效果:
:root {
--style-queries-supported: check;
}
@container style(--style-queries-supported: check) {
body {
--style-queries-supported: yes;
}
}
接著,請在 JavaScript 中檢查計算值,如下所示:
if (getComputedStyle(document.body).getPropertyValue("--style-queries-supported") === "yes") {
// Use container style queries
} else {
// Use fallback strategy
}